虚拟存储

页号、页框

CPU运行一个4GB的程序,要求程序的代码和数据必须连续,顺序执行。而现实的内存是分散的不连续的。

如何将连续的4GB程序代码塞入2GB的主存中?

操作系统给CPU虚拟的连续的4GB的地址,而这个连续大地址的最小单位就是, 页的大小是固定的4KB。 连续编号,从0开始…

页框

真实的物理主存地址是不连续的,分散的。

操作系统也把主存切成了大小相等的标准网格——页框。页框大小也是4KB,连续从0开始编址。

操作系统可以将连续的虚拟内存分配到任意一个页框中。

CPU寻址时发出一个32位的虚拟地址,去内存中寻找数据。页大小为4KB,即2^12字节,也就是一个页框中有2^12个地址,即低位需要12位去页内寻址。当Cache满后替换“计数器”最小的块。 高20位即为虚拟页号,将这个虚拟页号去页表中查询页框号,后将高20位转换成真实的页框号。

  • 低位需要12位:页内偏移量

  • 高32-12=20位:虚拟页号

页表

将虚拟页地址映射到物理页框。

页表是在主存中存放的一个连续的一维数组,数组的索引即为页号,数组的内容为页表项

  • 页表项:物理页框号 + 有效位(装入位) + 脏位 + 引用位

  • 有效位表示的是该页是否从磁盘中装入到了主存中。

从CPU发出的虚拟地址到翻译为真实物理地址是依靠MMU实现的。

  • CPU 发出了一个 32 位的虚拟地址 [ 20位虚拟页号 (假编号) | 12位页内偏移量 (真细节) ]

  • MMU中的PTBR(页表基址寄存器)存储的是页表在内存中的起始地址(每个进程有独立的基址)

  • 目标记录物理位置 = 起始地址 + (虚拟页号 × 每一个页表项的大小)

  • 若页表项有效位为1,则将高位替换成真实的物理地址,[ 真实的物理页框号 | 12位页内偏移量 ] = 真正的物理地址

两次访存

  1. 先算 PTE 的地址(用你的那个公式),去内存查一次字典,拿到真地址。

  2. 拿着真地址,再去内存拿一次真正的数据。

虚拟存储器只能采用全相联+回写法

页式存储缺点

  • 内存碎片:10KB的程序最后一个程序段只能占2KB,无法充分利用。

  • 页不是逻辑上的独立实体,处理,保护,共享不方便:共享代码(指令代码,printf)只在内存中存放一份(Read-only),在进行分页的时候可能将共享的代码和数据代码分到一页中 页式存储只认大小

多级页表

快表(局部性原理)

访存的时候需要两次查找过程,拉低了CPU的处理速度。

TLB(Translation Lookaside Buffer,旁路转换缓冲),直接放在MMU中,使用SRAM做成的Cache。

快表上记录了最近刚翻译的页号——真实物理地址,CPU发出一个寻址地址后,MMU先查快表,若TLB命中则直接拿到真实的物理页框号。若TLB Miss则进行两次访存,并记录到TLB中。

TLB使用全相联或者组相联,内容由页表项 + TLB标记组成

TLB 虚拟地址映射到TLB块中。

  • 全相联:TLB标记即为虚拟地址号。

  • 组相联:TLB标记存的是虚拟地址号的高位。