当前位置: 代码迷 >> 综合 >> 2020-1-22
  详细解决方案

2020-1-22

热度:99   发布时间:2023-10-14 11:34:19.0

2020-1-22

  • 分页
    • 分页与分段
    • 多级页表
      • 超越两级
  • 超越物理内存
    • 机制

分页

线性页表有可能会非常耗费空间,假设我们有一个16kb的地址空间和1kb的页
2020-1-22
2020-1-22
2020-1-22
可以看到有很大一部分都没被使用

分页与分段

一种不太好的解决方案是混合分页和分段,也即为每个逻辑分段构建各自的页表
我们将进程分为三个段,代码段、堆段和栈段,每个段都与之前提及的分段一样,有一个基址寄存器和界限寄存器,要确认地址引用的哪个段,我们可以使用地址空间的前两位标记,例如00是未使用的段,01是代码,10是堆,11是栈,虚拟地址如下所示
2020-1-22
在得知使用哪个段后,就可以根据分段的基址寄存器找到对应的段的页表了,基址寄存器里放的是该段的线性页表的位置,再根据VPN和Offset就可以从页表里查到物理地址了

多级页表

另一种方式不依赖于分段,而是将页表分开,分成页大小的单元,然后使用页表目录来管理,如果改单元里的所有页都未被使用,就完全不给他分配资源
2020-1-22
但是这样做的问题是,在TLB未命中的情况下,会多出一次查找页表目录的操作
为了更好地理解多级页表背后的想法,我们来看一个例子。设想一个大小为 16KB 的小地址空间,其中包含 64 个字节的页。因此,我们有一个 14 位的虚拟地址空间,VPN 有 8位,偏移量有 6 位。要为这个地址空间构建一个两级页表,我们从完整的线性页表开始,将它分解成页大小的单元。回想一下我们的完整页表(在这个例子中)有 256 个项;假设每个 PTE 的大小是 4
个字节。因此,我们的页大小为 1KB(256×4 字节)。鉴于我们有 64 字节的页,1KB 页表可以分为 16 个 64 字节的页,每个页可以容纳 16 个 PTE。
2020-1-22
2020-1-22

超越两级

如果我们地址空间大,而页小,这时就需要超过两级的多级页表
让我们举一个简单的例子,用它来说明为什么更深层次的多级页表可能用。在这个例子中,假设我们有一个 30 位的虚拟地址空间和一个小的(512 字节)页。因此我们的虚拟地址有一个 21 位的虚拟页号和一个 9 位偏移量。
请记住我们构建多级页表的目标:使页表的每一部分都能放入一个页。到目前为止,我们只考虑了页表本身。但是,如果页目录太大,该怎么办?
要确定多级表中需要多少级别才能使页表的所有部分都能放入一页,首先要确定多少页表项可以放入一页。鉴于页大小为 512 字节,并且假设 PTE 大小为 4 字节,你应该看到,可以在单个页上放入 128 个 PTE。
2020-1-22
但是这里的页目录有14位,相当于有128个页,为了解决这个问题,我们为树再加一层,将页目录本身拆成多个页,然后在其上添加另一个页目录,指向页目录的页。我们可以按如下方式分割虚拟地址:
2020-1-22

超越物理内存

机制

在之前,我们一直假设地址空间较小,可以让我们把他们全存在内存中,但真实情况并非如此,于是就有了交换技术
我们将当前未被使用的页存在硬盘中,等到要使用的时候再将它交换到物理内存中,同时将物理内存中不是用的页再交换到硬盘中,这样不管地址空间有多大,都放得下了