Skip to content

方法Method

多级页表与稀疏地址空间

Multilevel page table · Hierarchical page table

逐级拆分VPN并计算PTE的物理地址,给出稀疏页表空间账本、失败停点和未缓存遍历成本。

形式陈述 ​

多级页表把虚页到页框的映射存成定高索引树。上层条目指向下一层页表页,最末层叶条目给数据PFN与权限;不存在的上层分支可不分配整个子表。这里的树是翻译索引,数据页不必按虚地址连续分配。

OS-16使用两级页表:16位虚地址拆为[4位根索引 i1 | 4位叶索引 i0 | 8位offset]。每张表16项,每项16B,恰好占一页。根与中间表页来自内核保留页框,普通用户无法读写;上层项只记录“存在、下层PFN”,权限全部在叶项检查,不含大页和上层权限。

设根物理基址为r,第一步读r+16i1;存在时取得下层页框t,第二步读256t+16i0。叶项有效且权限允许,才以其PFN加offset形成数据物理地址。表页访问使用物理地址,不能递归要求先通过正在遍历的用户页表翻译,否则没有明确的起点。

直觉

平表为每个可能虚页预留一个槽。两级表把16个相邻虚页归为一组:只有该组至少需要一个驻留映射时才分配叶表。地址空间越稀疏、映射越聚集,省下的空叶表越多;若每组只映一个页,省空间效果会明显减弱。

查表不是把整个地址拿去“查树”。每层消费固定的几位,位宽决定分支数,PTE宽度决定条目字节地址。页框号、表页基址和条目地址是三个不同的量。

例子与边界

两个根完整走一遍 ​

P根在PFN0x01,即r=0x0100;根索引1指向叶表PFN0x02。Q根在PFN0x03,索引1指向PFN0x04。两张叶表的索引2分别映射到数据PFN0x30和0x50。

v=0x12AB给出i1=1,i0=2,o=0xAB。P先读根项物理地址0x0100+1×16=0x0110,得到0x02;再读0x0200+2×16=0x0220,得到0x30;最后访问0x30AB。Q相应读0x0310、0x0420,最后访问0x50AB。首次访问没有TLB命中、没有缓存表页时,两次PTE读取再加一次数据读取,共三次内存访问。

OS-16两进程页表遍历

若P访问0x2701而根索引2不存在,遍历在第一层停止,不能继续把零当下一层地址读内核页。若根存在而叶项不驻留,则停在第二层。软件随后查合法区域;两种停止位置都没有直接告诉它“应该杀死进程”还是“应该分配页”。

空间不一定总比平表省 ​

P仅映射VPN0x10、0x12、0x13时,共需根和一张叶表,512B。加入VPN0xF0后需第二张叶表,共768B。平表始终需256×16=4096B。若16个根分支都需要叶表,则两级结构占17页、4352B,比平表多一页;稀疏优化不意味着任何输入都更小。

按页分配表页时,新增某组第一个映射的成本包括清零整张叶表;新增同组的另一个映射只需改叶项。最后一个叶映射撤销后,只有确认没有并行遍历或缓存引用需要该表页,才可回收叶表。

推论与应用

对固定层数L,未缓存遍历最多读取L个PTE,成功数据访问再加一次。对一般每层f项、m个已映射虚页的树,空间取决于它们共享多少索引前缀,不能简单写成mL个新节点并称精确值。最坏按路径计上界可以,聚集映射通常共享很多上层页。

多级结构只解决表空间和查找组织,访问速度还需TLB。OS-16两级不是xv6的Sv39:rev5教材使用三个9位索引与12位偏移、8B PTE。把OS-16的地址直接套到Sv39会得到错误表项地址;同一分解方法可以迁移,参数必须重新取自ISA。

参考资料
关系图谱3 个相邻概念 · 2 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
类型化关系