CSAPP学习笔记 -- 第九章 虚拟内存(上)

虚拟内存的重要能力
  • 它将主存看成是一个存储在磁盘上的地址空间的高速缓存,在主存中只保存活动区域,并根据需要在磁盘和主存之间来回传送数据,通过这种方式,它高效地使用了主存
  • 它为每个进程提供了一致的地址空间,从而简化了内存管理
  • 它保护了每个进程的地址空间不被其他进程破坏。
 
学习虚拟内存的原因
  • 虚拟内存是核心的
  • 虚拟内存是强大的
  • 虚拟内存是危险的
 
9.1 物理和虚拟寻址

计算机系统的主存被组织成一个由M个连续的字节大小的单元组成的数组。每字节都有一个唯一的物理地址。
使用物理地址访问内存的方式称为物理寻址。
 
虚拟寻址:CPU通过生成一个虚拟地址(Virtual Address,VA)来访问主存,这个虚拟地址在被送到内存之前先转换成适当的物理地址。
将一个虚拟地址转换为物理地址的任务叫做地址翻译(address translation)。
CPU芯片上叫做内存管理单元(Memory Management Unit,MMU)的专用硬件,利用存放在主存中的查询表来动态翻译虚拟地址,该表的内容由操作系统管理。
 
 
9.2 地址空间

地址空间是一个非负整数地址的有序集合。
线性地址空间:地址空间中整数连续。
虚拟地址空间:虚拟地址的地址空间。
 
 
9.3 虚拟内存作为缓存的工具

VM系统将虚拟内存分割为虚拟页。类似的,物理内存被分割为物理页,也叫页帧。
  • 未分配的:VM系统还未分配(或者创建)的页。未分配的块没有任何数据和它们相关联,因此也就不占用任何磁盘空间。
  • 缓存的:当前已缓存在物理内存中的已分配页。
  • 未缓存的:未缓存在物理内存中的已分配页。
 
9.3.1 DRAM缓存的组织结构
  • SRAM缓存来表示位于CPU和主存之间的L1、12和L3高速缓存。
  • DRAM缓存来表示虚拟内存系统的缓存,它在主存中缓存虚拟页。DRAM缓存的组织结构完全是由巨大的不命中开销驱动的。因为对磁盘的访问时间很长,DRAM缓存总是使用写回,而不是直写。
 
9.3.2 页表
页表将虚拟页映射到物理页。每次地址翻译硬件将一个虚拟地址转换为物理地址时,都会读取页表。
 
9.3.3 页命中
 
9.3.4 缺页
触发一个缺页异常,缺页异常调用内核中的缺页异常处理程序,该程序会选择一个牺牲页,如果牺牲页已经被修改了,那么内核就会将它复制回磁盘。无论哪种情况,内核都会修改牺牲页的页表条目,反映出牺牲页不再缓存在主存中这一事实。当异常处理程序返回时,它会重新启动导致缺页的指令,该指令会把导致缺页的虚拟地址重发送到地址翻译硬件。
 
9.3.5 分配页面
在磁盘上创建空间并更新页表,使它指向磁盘上这个新创建的页面。
 
9.3.6 又是局部性救了我们
尽管在整个运行过程中程序引用的不同页面的总数可能超出物理内存总的大小,但是局部性原则保证了在任意时刻,程序将趋向于在一个较小的活动页面集合上工作,这个集合叫做工作集或者常驻集合。在初始开销,也就是将工作集页面调度到内存中之后,接下来对这个工作集的引用将导致命中,而不会产生额外的磁盘流量。
 
 
9.4 虚拟内存作为内存管理的工具

操作系统为每个进程提供了一个独立的页表
  • 简化链接。独立的地址空间允许每个进程的内存映像使用相同的基本格式,而不管代码和数据实际存放在物理内存的何处。
  • 简化加载。虚拟内存还使得容易向内存中加载可执行文件和共享对象文件。
  • 简化共享。独立地址空间为操作系统提供了一个管理用户进程和操作系统自身之间共享的一致机制。
  • 简化内存分配。虚拟内存为向用户进程提供一个简单的分配额外内存的机制。
 
 
9.5 虚拟内存作为内存保护的工具

每次CPU生成一个地址时,地址翻译硬件都会读一个PTE,所以通过在PTE上添加一些额外的许可位来控制对一个虚拟页面内容的访问十分简单。
如果一条指令违反了这些许可条件,那么CPU就触发一个一般保护故障,将控制传递给一个内核中的异常处理程序。Linux shell一般将这种异常报告为“段错误”
 
 
9.6 地址翻译

  • 图9-13a展示了当页面命中时,CPU硬件执行的步骤。
    • 第1步:处理器生成一个虚拟地址,并把它传送给MMU。
    • 第2步:MMU生成PTE地址,并从高速缓存/主存请求得到它。
    • 第3步:高速缓存/主存向MMU返回PTE。
    • 第4步:MMU构造物理地址,并把它传送给高速缓存/主存。
    • 第5步:高速缓存/主存返回所请求的数据字给处理器。
  • 页面命中完全是由硬件来处理的,如图9-13b所示。
    • 第1步到第3步:和图9-13a中的第1步到第3步相同。
    • 第4步:PTE中的有效位是零,所以MMU触发了一次异常,传递CPU中的控制到操作系统内核中的缺页异常处理程序。
    • 第5步:缺页处理程序确定出物理内存中的牺牲页,如果这个页面已经被修改了,则把它换出到磁盘。
    • 第6步:缺页处理程序页面调入新的页面,并更新内存中的PTE。
    • 第7步:缺页处理程序返回到原来的进程,再次执行导致缺页的指令。CPU将引起缺页的虚拟地址重新发送给MMU。因为虚拟页面现在缓存在物理内存中,所以就会命中,在MMU执行了图9-13b中的步骤之后,主存就会将所请求字返回给处理器。
 
9.6.1 结合高速缓存和虚拟内存
主要思路是地址翻译发生在高速缓存查找之前
 
9.6.1 利用TLB加速地址翻译
翻译后备缓冲器TLB是一个小的,虚拟寻址的缓存,其中每一行都保存着一个由单个PTE组成的块。
  • 图9-16a展示了当TLB命中时(通常情况)所包括的步骤。这里的关键点是,所有的地址翻译步骤都是在芯片上的MMU中执行的,因此非常快。
    • 第1步:CPU产生一个虚拟地址。
    • 第2步和第3步:MMU从TLB中取出相应的PTE。
    • 第4步:MMU将这个虚拟地址翻译成一个物理地址,并且将它发送到高速缓存/主存。
    • 第5步:高速缓存/主存将所请求的数据字返回给CPU。
  • 当TLB不命中时,MMU必须从L1缓存中取出相应的PTE,如图9-16b所示。新取出的PTE存放在TLB中,可能会覆盖一个已经存在的条目。
 
9.6.3 多级页表
这种方法从两个方面减少了内存要求
  • 第一,如果一级页表中的一个PTE是空的,那么相应的二级页表就根本不会存在。这代表着一种巨大的潜在节约,因为对于一个典型的程序,4GB的虚拟地址空间的大部分都会是未分配的。
  • 第二,只有一级页表才需要总是在主存中;虚拟内存系统可以在需要时创建、页面调入或调出二级页表,这就减少了主存的压力;只有最经常使用的二级页表才需要缓存在主存中。
 
9.6.4 综合:端到端的地址翻译
实例,略。
 
posted @ 2020-10-22 20:26  Yoke_cc  阅读(124)  评论(0编辑  收藏  举报