极致优化思想系列之一:操作系统内核极致提升空间效率的设计点滴
来源:互联网 发布:零点有数 知乎 编辑:程序博客网 时间:2024/05/24 13:28
《极致优化思想系列》是我用来收集一些不同目的诉求场景下的一些前人的精巧的极致设计思想,这些设计思路充满了艺术性,以此系列来作为敦促自我驱动不断进步之意。
《极致优化》的第一篇文章关注的便是“空间效率”这个最常见的criteria。而谈到空间的极致压榨利用,相信可能除了数据库便是操作系统了,由于数据库的技术暂时涉猎较少,故而本文先留白,留待日后不定期添加新的成员。
先引入Linux下的段地址对齐概念
问题: 内存页frame是映射的最小单位,对于Intel80x86CPU来说,默认的页大小为4KB,也就是说要映射的物理内存大小和起始地址必须是4096倍数,虚拟地址空间中的起始位置和大小也要满足4096倍数。但这样一来,物理内存和虚拟内存segment的直接映射可能会导致较多的内部碎片,如何解决?
答:省着用,两相连段接壤部分按4KB为单位共享一个物理页,然后该页做两次映射,记录在虚拟内存—物理页对应关系表中。因为段地址对齐的缘故,导致现在各个段的虚拟地址就往往不是系统页面长度的整数倍了。
减小内部碎片的努力,以尽可能提升内存空间的使用效率:
1.目标文件到可执行文件的链接过程中:多同名section段合并
2.可执行文件到虚拟空间VMA映射的装载过程:相同权限RWX的section相连排布,提出segment
3.虚拟空间VMA到物理内存页的对应过程运行:相连segment的接壤部分共用一个物理页4KB ,而这个物理页多做一次映射记录到“虚拟内存—物理页对应关系表中”。
注:只需要多付出一个目录项的空间便可以使用上一个VMA剩下的空间,这也导致0x1000不再作为虚拟空间分配的基础单位了,虚拟空间segment起始地址开始出现0x99E8这种地址,当然段起始地址还是要以4B为单位的,即可被4整除。
Linux采用混合多重索引结构,将将文件所占用盘块block的盘块号直接或间接地存放在该文件索引节点Iinode的地址项中,在Linux中索引节点被称为inode,大小128B,记录一个block要花费4B(32位系统),在EXT2/3系统规定inode中含有12个直接地址项,1个一次间接项(指向一重索引表),1个二次间接项(指向二重索引表),1个三次间接项(指向三重索引表)。
EXT2/3这种混合多重索引结构是种经典的平衡策略(取长补短,取直接块索引的快速,取间接索引的大容量),原因如下:
1. 直接寻址:因为Linux系统中以中小型文件流为主,几十KB很常见,这时采用直接寻址即采用inode中的12个直接地址项,可以有效减低IO次数,这也是这些块被称为直接块的原因;
2. 一次间接寻址:当文件达到几百KB时,Linux提供一次间接寻址,顶层索引节点中存放的是直接块的块号对应表;
3. 多次间接寻址方式,依次类推。
从上面分析可以看到,混合索引结构对于小文件保证快速访问,对于大文件也能提供较好的支持。是属于经典的时间-空间效率“鱼和熊掌兼得”的好设计。
未完待补……