《深入理解计算机系统》(9)内存管理

1、物理和虚拟寻址

  • 物理寻址
    • 主存被组织成一个由 M 个连续的字节大小的单元组成的数组。每字节都有一个唯一的物理地址。CPU 访问内存最自然的方式就是使用物理地址,称为物理寻址。
    • 下图是一个物理寻址的示例,该示例的上下文是一个加载指令,它读取从物理地址4开始的4个字节,并将它返回给CPU,CPU会将它放在一个寄存器里。
      在这里插入图片描述
    • 早期的PC、嵌入式微处理器DSP等仍然使用的是物理寻址的方式。
  • 虚拟寻址
    • 现代 CPU 使用的是虚拟寻址:CPU 通过生成一个虚拟地址(VA)来访问主存,这个虚拟地址首先通过地址翻译转换为物理地址
      在这里插入图片描述
    • 地址翻译需要 CPU 硬件和操作系统之间的紧密合作。CPU 芯片上名为内存管理单元(MMU)的专用硬件利用存放在主存中的查询表来动态翻译虚拟地址

2、地址空间

  • 地址空间(address space)
    地址空间是一个非负整数地址的有序集合:{0, 1, 2, …}
  • 线性地址空间(linear address space)
    地址空间中的整数是连续的
  • 虚拟地址空间(virtual address space)
    在计算机系统中,CPU 从一个有 N=2^n 个地址的地址空间中生成虚拟地址空间{0, 1, 2, … ,N-1} 。一个地址空间的大小是由表示地址的位数来描述的,例如现代的 64 位计算机一般支持 64 位虚拟地址空间。
  • 物理地址空间(physical address space)
    对应系统中物理内存的M个字节:{0, 1, 2, … ,M-1},M不要求是2的幂,但我们假设M=2^m。

3、虚拟内存作为缓存的工具

  • 虚拟内存被组织为一个由存放在磁盘上的N个连续的字节大小的单元组成的数组。
  • 磁盘上的数组内容被缓存在主存中。和存储器层次结构中的其他缓存一样,磁盘(较低层)中的数据被分割成,作为磁盘和主存(较高层)之间的传输单元。
  • 类似的,物理内存被分割为物理页(PP),大小也是 P 字节。物理页也被称为页帧
  • 任何时刻,所有的虚拟页都被分为了三个不相交的子集:
    • 未分配的:VM 系统还未分配(未创建)的页。未分配的块没有任何数据与它们相关联,因此不占用任何磁盘空间。
    • 已缓存的:当前已缓存在物理内存中的已分配页。
    • 未缓存的:未缓存在物理内存中的已分配页。
      在这里插入图片描述
      图中展示了一个有8个虚拟页的小虚拟内存。虚拟页0和3还没有被分配,即在磁盘中不存在。虚拟页1、4和6被缓存在物理内存中。虚拟页2、5和7已经被分配,但并未缓存在主存中。

3.1、DRAM缓存的组织结构

  • 主存一般采用 DRAM,DRAM 与磁盘之间的速度差要比 SRAM 与 DRAM 之间的速度差大很多,并且从磁盘的一个扇区读取第一个字节的时间开销比读这个扇区中的连续字节要慢很多。因此 DRAM 缓存的组织结构与高速缓存有很大不同。
  • 因为严重的不命中处罚和访问第一个字节的开销,虚拟页一般很大,通常在 4KB~2MB,且 DRAM 缓存是全相联的,即任何虚拟页都可以放在任何的物理页中。不命中时的替换策略也很重要。
  • 因为访问磁盘很慢,所以 DRAM 都采用写回(即延时写),而非直写。

3.2、页表

  • VM 系统需要判定一个虚拟页是否缓存在 DRAM 中的某个地方,如果是需要确定虚拟页存放在哪个物理页中,如果不是需要判断虚拟页存放在磁盘的哪个位置;在 DRAM 中选择一个牺牲页并把虚拟页从磁盘复制到 DRAM 中替换这个牺牲页。
  • 这些功能由操作系统软件、MMU 中的地址翻译硬件、页表共同完成:
    • 页表(Page Table)是一个存放在 DRAM 中的数据结构,它将虚拟页映射到物理页
    • 每次地址翻译硬件将一个虚拟地址转换为硬件地址时都会读取页表。
    • 操作系统负责维护页表的内容,以及在磁盘和 DRAM 间传送页。
  • 页表是一个 页表条目(Page Table Entry,PTE) 构成的数组,虚拟地址空间中的每个页在页表中的一个固定偏移量处都有一个 PTE。可以认为 PTE 由一个有效位和一个 n 位地址字段组成。有效位表明该虚拟页是否被缓存在 DRAM 中。
    在这里插入图片描述
  • 对于三种不同的页,其页表条目的内容不同:
    • 已缓存的页: 有效位=1,n 位地址字段表示该页在 DRAM 中相应的物理页的起始地址。
    • 未缓存的页: 有效位=0,n 位地址字段表示该虚拟页在磁盘上的起始地址。
    • 未分配的页: ss有效位=0,地址字段为空。

3.3、页命中

在这里插入图片描述

  • 当 CPU 要读取上图中的 VP2 就会发生页命中
  • 地址翻译硬件使用虚拟地址作为索引从页表中查找相应的页表条目,然后读取条目中的内容来获取该虚拟页在 DRAM 中的物理地址。

3.4、缺页

在这里插入图片描述

  • DRAM 缓存不命中称为缺页。如 CPU 要读取上图中的 VP3 时,会从页表条目的有效位发现该页没有被缓存。
  • 当发生缺页会触发一个缺页异常。缺页异常会调用内核中的缺页异常处理程序,该程序会从已缓存的页中选择一个牺牲页。如果该牺牲页之前已经被修改,内核会先将它复制回磁盘(即写回),然后内核会占用它的物理页并修改它的页表条目为未缓存的。(注意下图指向VP4的PTE中的有效位置为0了)
    在这里插入图片描述
  • 缺页异常处理完成后,会重新启动导致缺页的指令,该指令重新进行对该虚拟地址的操作。
  • 一些概念
    • 在磁盘和内存之间传送页的活动叫做交换(swapping)或者页面调度(paging)。
    • 页从磁盘换入DRAM和DRAM换出磁盘。
    • 一直等待,直到有不命中发生时才换出页面的策略称为按需页面调度,该策略被所有现代系统使用。

3.5、分配页面

  • 初始的虚拟地址空间中的虚拟页基本都是未分配的,当调用了 malloc 就会分配一个或一些新的虚拟页,这些页指向磁盘上的对应页面
    在这里插入图片描述

3.6、又是局部性救了我们

  • 虚拟内存利用了局部性,局部性原则保证了在任意时刻,程序将趋向于在一个较小的活动页面集合(称为工作集)上工作。
  • 通过将活动页面集合(称为工作集)缓存到 DRAM 中来减少出现缺页的情况。
  • 如果工作集的大小超出了 DRAM 的大小,程序将会发生抖动,页面会不断地换进换出
  • 根据本节内容可以区分主存缓存与各高速缓存的组织结构的不同之处:
    • 高速缓存将地址位划分为有效位、标记位、组索引位、块偏移位,通过组选择行匹配字抽取来完成对数据的操作。
    • 主存采用了 VM 系统,使用页表来实现对数据的查找。

4、虚拟内存作为内存管理的工具

  • 实际上每个进程都会有一个独立的虚拟地址空间,也都有一个独立的页表。不同进程的虚拟页面可能映射到同一个物理页面上。
    在这里插入图片描述
  • 通过按需页面调度独立的虚拟地址空间,VM 在内存管理时实现了以下功能:
    • 简化链接。独立的地址空间允许为每个进程的内存映像使用相同的基本格式,如代码段都是从 0x400000 开始,数据段都在代码段后,栈从用户进程地址空间最高的地方向下生长等。因为采用了虚拟地址,所以这些可执行文件是独立于物理内存中代码和数据的最终位置的。
    • 简化加载。当要向内存中加载可执行文件和共享对象文件时,Linux 加载器为代码段和数据段分配虚拟页并将其标记为无效的(即未缓存的),将页表条目指向目标文件中适当的位置即可。将一组连续的虚拟页映射到任意一个文件中的任意一个位置叫做内存映射
    • 简化共享。独立地址空间为操作系统提供了一个管理用户进程与操作系统自身之间共享的一致机制。操作系统通过将不同进程中适当的虚拟页面映射到相同的物理页面,从而安排多个进程共享这部分代码的一个副本,而不是在每个进程中创建单独的副本。
    • 简化内存分配。当一个进程要求分配堆空间时,操作系统分配 k 个的连续的虚拟内存页面,并将它们映射到物理内存中任意位置的 k 个任意的物理页面。由于页表工作的方式,物理页面不需要是连续的。

5、虚拟内存作为内存保护的工具

  • 每次 CPU 生成一个虚拟地址时,地址翻译硬件都会读一个 PTE,可以通过在 PTE 上添加一些额外的许可位来控制对一个虚拟页面内容的访问。
    在这里插入图片描述
  • 上图中每个 PTE 都添加了三个许可位:
    • SUP 表示进程是否必须运行在内核模式下才能访问该页。
    • READ 控制读的权限。
    • WRITE 控制写的权限。

6、地址翻译

  • 地址翻译是通过硬件实现的。地址翻译是一个 N 元素的虚拟地址空间(VAS)和一个 M 元素的物理地址空间(PAS)之间的映射。
    在这里插入图片描述
  • CPU 中有一个页表基址寄存器指向当前页表。n 位的虚拟地址包含 p 位的虚拟页面偏移和 n-p 位的虚拟页号。MMU(内存管理单元) 利用虚拟页号来选择适当的 PTE,然后将 PTE 中的物理页号和虚拟地址中的虚拟页偏移量串联起来就得到了对应的物理地址。
    在这里插入图片描述
  • 页面命中时 CPU 硬件执行的步骤:
    • 处理器生成一个虚拟地址,并把它传送给 MMU。
    • MMU 根据虚拟地址生成 PTE 地址,并从主存请求得到它。
    • 主存向 MMU 返回 PTE。
    • MMU 构造物理地址,并把它传送给主存。
    • 主存返回所请求的数据字给处理器。
      在这里插入图片描述
  • 缺页时 CPU 硬件执行的步骤:
    • 处理器产生一个虚拟地址。
    • MMU生成PTE地址,并从高速缓存/主存请求得到它。
    • 高速缓存/主存向MMU返回PTE。
    • PTE中的有效位是零,所以MMU触发了一次异常,传递CPU中的控制到操作系统内核中的缺页异常处理程序。
    • 缺页处理程序确定出物理内存中的牺牲页,如果这个页面已经被修改了,则把它换出到磁盘。
    • 缺页处理程序页面调入新的页面,并更新内存中的PTE。
    • 缺页处理程序返回到原来的进程,再次执行导致缺页的指令。CPU将引起缺页的虚拟地址重新发送给MMU。因为虚拟页面现在缓存在物理内存中,所以就会命中,主存就会将所请求字返回给处理器。
      在这里插入图片描述

6.1、结合高速缓存和虚拟内存

  • 下面展示了一个物理寻址的高速缓存如何和虚拟内存结合起来。
    在这里插入图片描述

  • 大多数系统采用物理寻址来访问 SRAM 高速缓存,即先完成了地址翻译,再根据得到的物理地址到 SRAM 高速缓存中查找。

  • 因为访问权限的检查已经在地址翻译时完成,所以高速缓存无需处理保护问题

6.2、利用TLB加速地址翻译

  • 每次 CPU 产生一个虚拟地址,MMU 都要查阅一个 PTE,这带来了额外的开销。

  • 许多系统在 MMU 中包括了一个关于 PTE 的小的缓存——翻译后备缓冲器(TLB)。这样所有的地址翻译步骤在 MMU 中就可以执行完成。

  • TLB 采用了具有较高相联度的组相联方式,用于组选择行匹配的索引和标记字段从虚拟地址的虚拟页号中提取出来。
    -

  • 下面展示当TLB命中和不命中所包括的步骤。当 TLB 不命中时,MMU 需要从 L1 高速缓存中取出相应的 PTE 替换 TLB 中的某个已存在的条目。
    在这里插入图片描述

6.3、多级页表

  • 如果只用一个页表来进行地址翻译,该页表就会很大,比如一个 32 位的地址空间、4KB 的页面、4 字节的 PTE,就需要一个大小为 4MB 的页表(自行推算)。64 位的系统就更大了(2^32*4MB,非常大!)。为了压缩页表,常用多级页表。
  • 下面是一个二级页表的例子。
    在这里插入图片描述
    • 一个 32 位的地址空间中页面的大小为 4KB,则共有 1MB 个页面,可以将地址空间划分为 1024 个片,每个片包括 1024 个连续的页。
    • 一级页表的每个 PTE 负责映射虚拟地址空间中的一个片,二级页表的每个 PTE 映射一个页。
    • 如果某个片的 1024 个页面都没有被分配,那一级页表中这个片的 PTE 就是空的,只有该片中的页面被分配了,一级页表的 PTE 才会指向该片对应的二级页表的基址。
  • 多级页表从两个方面降低了内存需求:
    • 如果一级页表的 PTE 是空的,那相应的二级页表根本就不存在。
    • 只有一级页表和最常用的二级页表才总是在主存中,VM 系统可以在需要时才创建、页面调入或调出二级页表。
  • 下面是一个多级页表的例子
    在这里插入图片描述
    • 上图中虚拟地址被划分为了 k 个 VPN 和一个 VPO。每个 VPN i 都是一个到第 i 级页表的索引。
    • 第 k 级页表中的每个 PTE 包含某个物理页面的 PPN(物理页号)或一个磁盘页的地址。其他页表中的 PTE 则包含对应的下一级页表的基址。
    • 对于多级页表,要确定虚拟地址的物理页号,需要访问 k 个页表的 PTE。通过 TLB 将不同层次上页表的 PTE 缓存起来,但多级页表的地址翻译不比单级页表慢很多。

6.4、综合:端到端的地址翻译

  • 自行查看《深入理解计算机系统》P573-P575,有点绕,不想看就算了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Elec Liu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值