虚拟存储器
虚拟存储器是一个抽象的概念,主要目的是为多个程序之间有效而安全地共享存储器。它为每个进程提供了一个大的、一致的和私有的地址空间。
虚拟地址与物理地址
把主存看成是由连续字节单元组成的大数组,并且用物理地址来标识每个数组的单元。那么物理寻址如下图:
虚拟寻址如下图:
虚拟存储器与物理存储器
虚拟存储器被组织为一个由存放在磁盘上的N个连续的字节大小的单元组成的数组。和存储器层次结构中其他缓存一样,磁盘(较低层)上的数据被分割成块,这些块作为磁盘和主存(较高层)之间的传输单元。虚拟存储器分割为虚拟页,物理存储器被分割为物理页。其映射关系如下:
页表
页表是一个页表条目(PTE)的数组,维护了虚拟地址与物理地址的映射关系:
虚拟地址空间中的每个页在页表中一个固定偏移量处都有一个PTE,每个PTE是由一个有效位和一个n位地址字段组成。有效位表明了该虚拟页当前是否被缓存在DRAM中。根据有效位及地址段的不同情况,有如下三种可能:- 设置了有效位,那么地址字段就表示DRAM中相应的物理页的起始位置,这个物理页中缓存了该虚拟页。
- 未设置有效位,地址段为空,表示这个虚拟页还未被分配。
- 未设置有效位,地址段不为空,则地址指向该虚拟页在磁盘上的起始位置。
页命中与缺页
这个可以参照高速缓存,不进行过多解释了。
页命中:
缺页:
缓存不命中称为缺页,缺页异常调用内核中的缺页异常处理程序,该程序会选择一个牺牲页。当异常处理程序返回时,会重新启动导致缺页的指令。牺牲页是针对物理存储器的,对于页表来说其大小是固定的
如果工作集的大小超过了物理存储器的大小,会不断的导致缓存不命中,产生颠簸状态,页面将不断的换进换出。
虚拟存储器与存储器
操作系统为每个进程提供了一个独立的页表,因而也就是一个独立的虚拟地址空间:
任何现代计算机系统必须为操作系统提供手段来控制对存储器系统的访问。通过在PTE上添加一些额外的许可位来控制对一个虚拟页面内容的访问:
SUP位表示进程是否必须在内核模式下才能访问该页,READ与WRITE位控制对页面的读写访问。
地址翻译
地址翻译(虚拟地址–>物理地址)
过程见图:
其中,存储器管理单元(MMU)负责请求页表条目及翻译地址和缺页处理。MMU利用VPN来选择PTE,如VPN0选择PTE0。
高速缓存及TLB缓存PTE
在地址翻译的过程中,有一个步骤是通过页表条目地址来查找PTE,我们可以通过结合高速缓存来提高其查找速度:
TLB是专门用于虚拟寻址的缓存,称为翻译后备缓冲器:
多级页表
我们知道,页表存储了虚拟地址与物理地址的映射关系,并且对于页表映射了全部的虚拟地址空间。假如是32位的地址空间、4KB的页面和一个4字节的PTE,那么也总是需要4MB的页表驻留在存储器中。并且很多情况下,我们只会引用虚拟地址空间中的一小部分。
常用压缩页表的方法是使用多级页表。以一个二级页表为例:
一级页表中的每个PTE负责映射虚拟地址空间中一个4MB的片,如果片i中的每个页面都未被分配,那么一级PTEi就为空。二级页表中的每个PTE都负责映射一个4KB的虚拟存储器页面。
这种方法从两个方面减少了存储器要求。第一,如果一级页表中的一个PTE是空的,那么相应的二级页表就根本不会存在,这代表着一种巨大的潜在节约,因为对于一个典型的程序,4GB的虚拟地址空间的大部分都将是未分配的。第二,只有一级页表才需要总是在主存中;虚拟存储器系统可以在需要时创建、页面调人或调出二级页表,这就减少了主存的压力,只有最经常使用的二级页表才需要缓存在主存中。使用多级页表的地址翻译如下图:
在这种情况下,在确定PPN之前,MMU必须访问k个PTE。优化地址翻译
在地址翻译我们描述了两个步骤的过程:1) MMU将虚拟地址翻译成物理地址;2)将物理地址传送到Ll高速缓存。然而,实际的硬件实现中允许这些步骤部分重叠,当MMU向TLB请求一个页表条目时,Ll高速缓存正忙着利用VPO查找相应的组,并读出这个组里的八个标记和相应的数据字。当MMU从TLB得到PPN时,缓存已经准备好试着把这个PPN与这八个标记中的一个进行匹配了。
最后建议做一下《深入理解计算机系统(原书第2版)》547页的例题,可以对高速缓存及虚拟存储器的地址翻译有一个整体的认识。