Skip to content

L04:现代虚拟内存系统(Modern Virtual Memory Systems

MIT 6.5900 Fall 2024 · Daniel Sanchez 主题:地址翻译与保护、线性/层级页表、TLB、中断与异常、TLB 与 Cache 组织、现代用途


一、虚拟内存的演进与目标

演进脉络:多道程序需求 → 分段(基址/界限)→ 碎片问题 → 分页 → 程序放不下主存 → 按需分页

现代虚拟内存系统提供"大的、私有的、统一的存储"假象:

  • 保护与隐私:多用户各有私有地址空间 + 一个或多个共享地址空间;页表 ≡ 内存视图 ≡ 名字空间;
  • 按需分页:能运行超过主存的程序,隐藏机器配置差异;
  • 代价是每次访存都要地址翻译

二、地址翻译与保护

每条指令与数据访问都需地址翻译与保护检查。好的虚拟内存设计须空间高效快(约一个周期)

  • 虚拟地址 = <虚拟页号 VPN, 偏移 offset>
  • 物理地址 = <物理页号 PPN, offset>
  • 保护检查依据内核/用户模式、读/写权限,违例则产生异常。

三、页表

线性页表(Linear Page Table

页表项(PTE)*含:页是否存在的位、内存常驻页的 **PPN**、磁盘页的 **DPN**、保护与使用状态位。OS 在活动用户进程切换时设置*页表基址寄存器

线性页表的大小:32 位地址、4KB 页、4 字节 PTE → 220 个 PTE,即每用户 4MB 页表,并需 4GB 交换空间。

  • 更大页?→ 内部碎片(页内未全用)+ 更大缺页代价;
  • 64 位地址空间?即使 1MB 页也需 244 个 8 字节 PTE(35 TB!)。救赎在于:地址空间稀疏使用 → 层级页表。

层级页表(Hierarchical Page Table

把 VPN 拆成多级索引(如 10-bit L1 索引 + 10-bit L2 索引 + offset),按需只为用到的部分分配下级页表。不存在的页对应空 PTE。可支持多种页大小(某 L1 项直接指向大页)。


四、TLB(Translation Lookaside Buffer

地址翻译很昂贵——层级页表中每次引用变成多次访存。解法:在 TLB 中缓存翻译。

  • TLB 命中 ⇒ 单周期翻译;
  • TLB 缺失页表遍历(page table walk)回填。

TLB 项含:V/R/W/D 位、tag、PPN。

TLB 设计

  • 是否保存进程信息?无进程 ID → 上下文切换须刷新;每项打进程 ID(ASID)→ 不刷新但更贵;
  • 大小与相联度:通常 32–128 项、高相联;
  • TLB 覆盖范围TLB Reach):TLB 能同时映射的最大虚拟地址空间。例:64 项 × 4KB 页 = 256KB(若连续);
  • 增大覆盖范围的办法:多级 TLB(如 Skylake:64 项 L1 数据 TLB、128 项 L1 指令 TLB、1.5K 项 L2 TLB)、多种页大小(x86-64:4KB / 2MB / 1GB)。

TLB 支持多页大小

  • 统一 TLB:先按 4KB 算索引探测,缺失再按 2MB 重算索引探测;
  • 或为每种页大小设独立 TLB(与统一 TLB 各有利弊)。

处理 TLB 缺失

  • 软件(MIPS、Alpha):TLB 缺失触发异常,OS 遍历页表并重载 TLB,遍历用特权"未翻译"寻址模式;
  • 硬件(SPARC v8、x86、PowerPC):MMU 遍历页表并重载 TLB;遍历中遇到缺失页则放弃并对原指令发缺页异常

地址翻译全流程

虚拟地址 → TLB 查找(命中→保护检查→物理地址到 Cache);TLB 缺失 → 页表遍历(硬件或软件)→ 页在内存则更新 TLB,不在内存则缺页(OS 调页);保护检查失败 → 保护故障(SEGFAULT)。


五、中断与异常(Interrupts

中断:请求处理器关注的事件,改变正常控制流。

中断的原因

  • 异步(外部事件):I/O 设备服务请求、定时器到期、电源中断/硬件失效;
  • 同步(内部事件,即异常):未定义操作码、特权指令、算术溢出、FPU 异常、未对齐访存、虚拟内存异常(缺页/TLB 缺失/保护违例)、陷阱(系统调用)。

异步中断的处理

I/O 设备拉起某条优先级中断请求线;处理器决定处理时:在指令 Ii 处停下并完成到 Ii1 的所有指令(精确中断);把 Ii 的 PC 存入特殊寄存器(EPC);禁用中断并把控制转给内核态的中断处理程序。

中断处理程序:启用中断前先保存 EPC 以支持嵌套中断(需指令把 EPC 移入 GPR、需屏蔽进一步中断直到 EPC 被保存);读状态寄存器判断中断原因;用特殊间接跳转 mret(返回异常)启用中断、恢复用户模式、恢复硬件状态。

同步中断(异常)

由特定指令引起,一般该指令不能完成、需在处理后重启(流水线下需撤销一条或多条部分执行指令的效果);而陷阱(系统调用)则视为已完成(特殊跳转 + 切到内核态)。

缺页处理程序:定位(或创建)缺失页、从磁盘调入并更新页表(等待期间 CPU 可跑别的作业);无空闲页则换出一页(伪 LRU);因传页耗时(毫秒级),缺页完全由 OS 软件处理,未翻译寻址模式对内核访问页表至关重要。


六、TLB 与 Cache 组织

CPU 中的地址翻译

软件处理程序需缺页/保护违例上的可重启异常;TLB 缺失需硬件或软件机制回填。应对 TLB 额外延迟的机制:放慢时钟、流水化 TLB 与 Cache 访问、虚地址 CacheTLB/Cache 并行访问

虚地址 Cache(Virtual-Address Cache

把 Cache 放在 TLB 之前。

  • 优点:命中时一步完成;
  • 缺点:上下文切换须刷新(除非 tag 含 ASID);页共享带来别名(aliasing)问题。

别名:两个虚拟页映射同一物理页,虚地址 Cache 可能有同一物理数据的两份副本,对一份的写对另一份的读不可见。

通解:禁止别名在 Cache 中共存。直接映射的软件(OS)解法——共享页的各 VA 须在 Cache 索引位上一致,使所有访问同一 PA 的 VA 在直接映射 Cache 中冲突。

TLB 与 Cache 并行访问

若索引位 L 不经 TLB 即可获得(即索引来自页内偏移),则 Cache 与 TLB 可同时开始访问,待两者完成后做 tag 比较。

  • 设 Cache 索引 L + 块内偏移 b,页内偏移位数 k:当 L+bk 时可行;L+b>k 时不行(索引用到了 VPN 位)。

L1 大于页大小的问题

当 L1 > 页大小时,索引用到了会被翻译的位,VA1 与 VA2 可能都映射到同一 PA → 仍有别名。

虚索引物理 tag(VIPT)+ 相联组织:用虚索引并行查,待 PPN 已知后比较 2a 个物理 tag。

用 L2 反别名

  • 通常用统一 L2 同时支撑 L1 指令与数据 Cache,L2 包含二者;
  • MIPS R10000 反别名:若 VA1、VA2 都映射 PA 且 VA1 已在 L1/L2(VA1≠VA2),当 VA2 解析到 PA 后在 L2 检测到冲突 → 从 L1 清除 VA1、载入 VA2 ⇒ 无别名;
  • 物理寻址的 L2 也可用于在虚寻址 L1 中避免别名(L2 "包含" L1,存虚 tag)。

七、虚拟内存的现代用途

  • 桌面/服务器/手机处理器:完整的按需分页虚拟内存——机器间可移植、多用户/多任务保护、共享小物理内存、简化某些 OS 功能;
  • 向量超算与 GPU:有翻译与保护但无按需分页(让作业放进内存、避免抖动到磁盘、多为批处理、可重启向量指令难实现);
  • 多数嵌入式处理器与 DSP:只提供物理寻址(负担不起虚拟内存的面积/速度/功耗,常无次级存储可换,程序为特定内存配置定制)。

小结

  • 现代虚拟内存提供大/私有/统一存储的假象,靠页表 + TLB 在每次访存做地址翻译与保护;
  • 层级页表利用地址空间稀疏性解决 64 位下页表过大的问题,TLB 缓存翻译并可经多级/多页大小扩展覆盖范围;
  • 中断分异步(外部)与同步(异常/陷阱),用精确中断与 EPC 支持可重启;
  • TLB 与 Cache 可并行访问(受索引位约束),虚地址 Cache 的别名问题可用 OS 约束或 L2 反别名解决。

下一讲:流水线(Pipelining)