本章小结:
页表:多级页表、倒排页表和性能
在使用虚拟内存时,必须做出几个关键决策
- 什么时候取页?需求还是预分页
- 哪些页面从内存中删除 ⇒ 页面替换算法
最优和FIFO页面替换算法
回顾:
虚拟内存依赖于构成一起被使用的页面组的位置,例如,与功能(代码、数据等)相关的位置。
- 进程在不同的位置之间移动
- 如果所有需要的页面都在内存中,则不会生成页面错误
页表变得更复杂(存在/不存在位,引用/修改位)和更大
页面表的再探讨
[多级]页表的访问速度
多级页表的内存组织:
- 根页表始终维护在内存中
- 页表本身由于其大小而维护在虚拟内存中
假设从主存取数据需要T纳秒
- 对于单页表级别,访问权限为2×T
- 对于两个页表级别,访问权限为3×T
- ……
有了两个级别,每个内存引用都变得慢了3倍:
- 假设第二级页表已经在主存中
- 在正常情况下,内存访问已经形成瓶颈
转换暂置缓冲区(Translation Look Aside Buffers,TLBs)
转换暂置缓冲区(TLBs)(通常)位于内存管理单元内部
- 它们缓存最常用的页表项
- 它们可以并行搜索
tlb背后的原理类似于操作系统中其他类型的缓存
记住:局部性(locality)表明进程对少量页面进行大量引用
使用TLB访问内存:
- 假设有一个单级页表
- 假设关联TLB查找为20ns
- 假设内存访问时间为100ns:①TLB Hit⇒20 + 100 = 120 ns ②TLB Miss⇒20 + 100 + 100 = 220ns
TLB性能评价:
- 对于80%的命中率。估计访问时间为:120×0.8+220×(1−0.8)= 140 ns(即40%的减速-相对于绝对寻址)
- 对于98%的命中率,估计的访问时间为:120×0.98+220×(1−0.98)= 122ns(即22%的减速)
注意,页表可以保存在虚拟内存中。由于页错误,页表会进一步(初始)变慢。
倒置页面表
“常规”的页面表大小与虚拟地址空间中的页面数量成正比(对于现代计算机来说过于庞大)
“倒置”(“inverted”)的页面表大小与主存的大小成正比
- 每个帧(即不是每个页面)都有一个条目
- 通过帧编号/哈希码进行索引(而不是通过页面编号)
- 当一个进程引用一个页面时,操作系统必须在(整个)倒置页面表中搜索相应的条目(即页面和进程标识)⇒ 这可能会太慢。
解决方案:使用一个将页面编号(n 位)转换为倒置页面表(哈希表)中索引的哈希函数
倒置的页面表条目
进程标识符(Process Identifier,PID):拥有此页面的进程。
页面编号(逻辑地址空间)
保护位(读/写/执行)
链接指针:该字段指向下一个条目(哈希表可能会出现冲突)
优点:
- 操作系统为所有进程维护一个单一的倒置页表
- 节省了空间(尤其是在虚拟地址空间远大于物理内存的情况下)
缺点:
- 逻辑地址到物理地址的转换变得更加困难/变慢了。
- 必须处理冲突,并且这会降低地址转换的速度:①哈希表避免了对整个倒置表的搜索 ②TLB有助于提高性能
页面加载/替换
使用虚拟内存时需要做出两个关键决策
- 哪些页面会被加载以及何时加载 ⇒ 可以进行预测
- 哪些页面会被从内存中移除以及何时移除 ⇒ 页面替换算法
页面会在主存储器和辅助存储器之间来回移动
需求分页(Demand Paging)
需求分页按需提供
需求分页始于内存中没有页面的初始状态
- 第一条指令会立即引发页面错误
- 随后还会出现更多的页面错误,但随着时间推移,这些错误会逐渐稳定下来,直至转移到下一个存储区域(locality)
- 当前正在使用的页面集合被称为其工作集working set(⇔驻留集resident set)
只有在需要时才会加载页面,即在发生页面错误之后才会加载。
预分页(Pre-Paging)
当该进程启动时,所有预期要使用的页面(即工作集)都可以一次性被加载到内存中。
- 这可以大幅降低页面故障率(page fault rate)。
- 检索多个(连续存储的)页面可以减少传输时间(寻道时间、旋转延迟等)。
预分页会在产生页面故障/错误之前(尽可能多地)加载页面(⇒ 当进程被换出/换入时也会使用类似机制)
实施细节
避免不必要的页面以及页面的替换是很重要的!
让:
- ma 表示内存访问时间(对于多级页表而言,该值会多次出现);
- p 表示页面故障率;
- pft 表示页面故障时间。
那么,有效访问时间可表示为:Ta = (1 - p) × ma + pft × p
需要注意的是,这里并未考虑 TLB。
需求分页系统的性能评估
对于单级页表:
- 内存访问时间为 100 纳秒(10^(⁻9) 秒))
- 需要进行两次内存访问(耗时 200 纳秒)
- 页面故障时间为 8 毫秒(10⁻³,要知道硬盘的读写速度较慢)
Ta = (1 - p)×200 + p ×8000000
有效访问时间与页面故障率成正比
- 理想情况下,所有页面都应无需分页机制而被加载到内存中
页面替换
概念
当新页面被加载且所有页面都被占用时,操作系统必须选择一个页面进行删除。
这一选择是由页面替换算法做出的,并会考虑以下因素:
- 该页面最后一次被使用的时间/预计下次再次使用的时间
- 该页面是否已被修改(只有被修改的页面需要进行写入操作)
必须明智地做出替换选择(即非随机选择),以节省时间/避免出现混乱状态。
算法
- 最优(Optimal)页面替换
- 先进先出(FIFO)页面替换:①第二次机会替换 ②时钟替换
- 不最近使用(Not recently used,NRU)
- 最近不使用(Least recently used,LRU)
最优页面替换
在理想/最优的世界里
- 每一页都会被标注出将要执行的指令数量或再次被使用之前的时长
- 那些长时间内都不会被引用的页面才是最应该被移除的页面
这种最优策略无法实际应用
- 它可以用于执行后的分析——即最小的页面故障次数会是多少
- 它为页面故障次数提供了一个下限(用于与其他算法进行比较)
理解
- 使用转换缓存以加快对页表的访问速度
- 倒置页表
- 获取策略(按需分页、预分页)
- 页面替换策略
假设页面/帧的大小为 4KB,地址空间为 16 位,则计算:
- 页面内偏移量所需的位数 M
- 表示页面所需的位数 N
使用此页表,0、8192、20500 的物理地址分别是多少?
答:① M = 12 位;N = 4 位;② 0 → 8192;8192 → 24576;20500 → 12308
一、地址划分
-
页/帧大小 = 4 KB = 4096 B = 2¹² B
⇒ 页内偏移 M = 12 位 -
地址总线 16 位
⇒ 页号 N = 16 − 12 = 4 位
二、按给定页表计算物理地址
公式:物理地址 = 帧号 × 4096 + 页内偏移
| 虚拟地址 | 页号 (VPN) | 偏移 | 查表得帧号 | 物理地址 |
|---|---|---|---|---|
| 0 | 0 | 0 | 2 | 2×4096+0 = 8192 |
| 8192 | 2 | 0 | 6 | 6×4096+0 = 24576 |
| 20500 | 5 | 20 | 3 | 3×4096+20 = 12308 |

被折叠的 条评论
为什么被折叠?



