虚拟存储的硬件支持¶
动机:让每个进程拥有自己的地址世界¶
程序希望地址连续、容量足够且不被其他进程破坏,物理内存却有限而零散。虚拟存储在虚拟地址与物理地址之间加入映射,同时提供:
- 进程隔离与页级权限;
- 灵活装载和共享;
- 按需把冷页面换到外存;
- 给程序近似连续的地址空间。
操作系统决定映射策略,硬件负责在每次访存的关键路径上快速翻译并检查权限。
页与页表¶
虚拟地址分为虚拟页号 VPN 和页内偏移:
页表项(PTE)把 VPN 映射到物理页号 PPN,并保存有效位、读写执行权限、访问位和脏位等。页内偏移在翻译前后不变:
若页大小为 4 KiB,页内偏移为 12 位。
为什么需要多级页表¶
若为巨大虚拟地址空间的每个页都预留 PTE,页表本身会很大。多级页表把 VPN 切成多段,只为实际使用的区域分配下级表,类似稀疏树。
代价是一次 TLB miss 可能需要多次内存访问才能走完页表。页表深度越大,地址空间扩展越容易,遍历代价也越高。
TLB:翻译的 cache¶
TLB 缓存近期 VPN 到 PPN 的映射与权限。命中时可很快形成物理地址;miss 时由硬件页表遍历器或操作系统查页表,成功后回填 TLB。
若 TLB 命中时间为 \(T_{TLB}\),命中率为 \(h\),页表遍历平均代价为 \(P\),忽略重叠时翻译开销近似:
真实机器会让 TLB 查询与 cache 索引部分重叠,以缩短关键路径。
TLB miss 不等于缺页¶
TLB miss¶
翻译不在小型 TLB,但对应 PTE 可能就在内存中且有效。遍历页表、回填后即可重试,通常不需从磁盘读数据。
page fault¶
PTE 表示页面不在主存、权限不允许或映射不存在,硬件触发异常。操作系统检查原因;按需调页时可能选择牺牲页、写回脏页、从 SSD 读入目标页、更新 PTE,再重启原指令。其代价可比普通指令高许多个数量级。
最小路径:一次 load¶
lw x5, 8(x10) 形成虚拟地址后:
- VPN 查询 TLB;
- 命中则得到 PPN并检查读权限;
- PPN 与原页内偏移组成物理地址;
- 物理地址查询 L1 data cache;
- cache 命中返回数据,最终写
x5。
若 TLB miss,先页表遍历;若 cache miss,再访问下级 cache 或 DRAM。两类 miss 独立存在。
大页与覆盖范围¶
同样数量的 TLB 项,页越大,能覆盖的内存越多,适合大数据和数据库;也能减少页表层级。但大页增加内部碎片、分配困难和换页粒度,未必适合零散小对象。
TLB reach 为:
提升 reach 可以增加项数、增大页或混合页大小,各有面积、延迟和管理成本。
cache 与翻译的先后¶
物理索引物理标记最直观,但必须等翻译后才能索引。虚拟索引可与 TLB 并行,却要处理不同虚拟地址映射同一物理页的同义问题,以及不同进程相同虚拟地址的重名问题。常见 L1 使用“虚拟索引、物理标记”,并让索引只依赖页内偏移范围。
权限、上下文与安全¶
PTE 的用户/内核、可写、可执行位是硬件隔离基础。切换进程后,旧 TLB 项不能被错误复用,系统可刷新 TLB 或用地址空间标识符区分。
推测执行还可能在权限检查结果确定前触碰 cache,形成侧信道。因此翻译与权限不只是性能机制,也是安全边界。
自测¶
- 4 KiB 页为何对应 12 位页内偏移?
- TLB miss、page fault 和 cache miss 各自缺少什么?
- 大页提高 TLB reach 的同时会带来哪些代价?