接下来是空间。如何削减页表占用的大量空间?

增加页大小

页表这下小了,但内部碎片又变大了。

混合方法:分页与分段

对每个逻辑段维护一个长度可变的页表。

好的,空间节省了,但分段的问题又回来了。

多级页表

基础分块算法的应用,相当优雅。

将整个页表切分成多个页大小的单位,每个单位作为页表的一部分存储在物理页框中。对页表单位建立树形的目录,每个页目录表 (page directory table, PDT) 同样由页表单位组成。

  • 虚拟地址空间相当稀疏:若页目录表索引的所有页表项均无效,就无需给这些页表项(与相应的下级页目录表项)分配物理内存!这极大地节省了空间使用。
  • 由于所有页表与页目录表单位均与页大小一致,它们可以存储在物理内存的不连续位置。
  • 以时间换空间:TLB 未命中后的页表查询更加耗时了。

每个页目录表项 (PDT entry, PDTE) 包含一个 PFN(若存在,指向有效的下级页目录表单位/页表单位的物理页框位置),一个有效位。

关键量

虚拟空间大小 <=> 虚拟地址位数。
页大小 <=> offset 位数。
VPN 位数 $=$ 虚拟地址位数 $-$ offset 位数。
页大小 $\div$ PTE 大小 $=$ 单页 PTE 数目 $=$ 单页 PDT 索引的单页 PT 数目 <=> 虚拟地址中某级页表的索引位数。

反置页表

在极端的物理空间资源受限的情况,可以使用反置页表 (inverted page table)

不维护虚拟空间到物理空间的映射,而是反过来,维护物理空间 (PFN) 到虚拟空间 (VPN) 的映射:某个页框正在被某个线程的某个虚拟页使用。

在查询时使用哈希函数,链表解决哈希冲突。