《Operating System:Three Easy Pieces》阅读笔记<十二>—分页(三)(small tables)

135 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情

分页(三)—现代页表

如果简单的使用linear page table,也就是一个内存占用对应一个page table entry,那么每个进程的page table所占用的内存加起来会十分巨大。如果不解决这一问题page将难以实用。我们有许多不同的思路来解决这一问题。

一个 32位地址空间,页大小为4KB,page table entry大小为4 bytes的系统,一个进程最多有4MB的页表大小。100个进程就是400MB,这种大小的占用对于现代系统来说是不可接收的。

首先是直接增大page size。假如增大n倍的page size,那么page table的空间占用也会减少n倍,但是很明显这样会造成internal fragmentation问题,page size越大,page内部空间被浪费的概率就越高。不过由于这一方法的实现简单,现在multiple page size被应用于不少现代体系结构如MIPS、SPARC、x86-64等,但是主要是用于减少TLB miss的压力,而不是节省页表空间。

试想一下,我们其实没有必要给地址空间中未被实际使用的内存分配page table entry,如下图所示,valid为0的page table entry并不需要记录,为了做到这一点,我们需要更改page table的存储结构。

因此另一种更加复杂的思路是混合page和segment,给进程中每一个segment一个page table,同样的,给每一个segment配一对base-bound。只不过这里的base用于记录page table的起始物理地址,bound用于记录page table的结束物理地址。通过这种方式page table只记录已经分配的部分,大大减少了page table的内存消耗,但是这样的话就又会出现segmentation的external fragmentation问题(治标不治本)。

page table只是数据结构,我们用很多方式去更改它以达到我们需要的目的,一种方式是multi-level page table多级页表。它的基本思想就是,如果一个page没有被具体分配,那么就不在page table里给它分配空间。听上去和hybrid有些像是么?但是我们不依靠segment,而是使用一种更灵活的实现方式,以两级页表为例,定义一种新的线性数据结构page directory。其中的内容称为page directory entry,包含两个基本信息,valid bit和PFN,如果valid bit为0,则不需要记录PFN。如果valid bit为1,则可直接通过PFN找到所属的page进行访问,抽象结构如图所示

multi-level page table有两个好处,一是最为关键的,由于它只给地址空间中正在使用的部分分配页表空间,因此天然是紧凑的并且支持稀疏的地址空间。二是page directory中每一个entry都完整的在一个page中(如图中所示),这使得它本身的空间容易进行管理,操作系统可以简单的进行增删。

但是multi-level page table也有两个坏处,一是明显的,当出现TLB miss时,它所耗费的代价更大,因为需要两次访问进行新table的构建。二是增加了页表查找的复杂度,这一点和第一个缺点类似。

我们以一个实际的例子来理解multi-level page table的工作过程,一个地址空间大小为16KB,page size为64 bytes,那么virtual address为14位,其中8位是VPN,6位是offset。假如还是使用linear page table的话,page table有256个entry,每个entry占用4 bytes,那么这些entry一共占用16个pages,也就是说我们需要4个bit位的page directory index来进行page table的page索引,这4个位包含在VPN中,余下4个bit位用于在page中索引page table。如下图所示

索引到page directory后,根据page directory对page table进行映射,在本例中,原本要占用16个连续pages的page table只占用3个pages,如下图所示

与TLB联系在一起,工作流程的伪代码如下

正如上面所说page table只是数据结构,还有其它更加节省空间的设计方式如inverted page tables等,但是更加小的空间占用无疑会带来更加大的索引开销,这依然是一个trade-off问题。并且内存问题并不是只有这一种解决思路,当内存紧张时,通过kernel virtual memory与硬盘进行swap也是一种page table内存问题的解决方法,不过这种内存极度紧张的情况并不多见。