2. 页表缓存原理:页表遍历过程与TLB如何加速虚拟地址到物理地址的转换
2.1 页表遍历:从虚拟地址到物理地址的软件/硬件协作
现代操作系统采用多级页表结构(如 x86-64 的 4 级页表)来管理虚拟地址空间。每次 CPU 访问内存时,MMU(内存管理单元)需要将虚拟地址转换为物理地址,这个过程称为页表遍历(Page Table Walk)。
核心概念:页表遍历本质上是多级索引查找。虚拟地址被划分为多个位段,每一段作为索引,在对应级别的页表中查找下一级页表的物理基地址,直到最后一级页表项(PTE)中包含最终的物理页帧号(PFN)。
以 x86-64 的 4KB 页、4 级页表为例,虚拟地址(48 位)的划分如下:
| 位段 | 名称 | 索引级别 | 页表名称 |
|---|---|---|---|
| 47:39 | PML4 索引 | 第 1 级 | PML4 表(Page Map Level 4) |
| 38:30 | PDPT 索引 | 第 2 级 | 页目录指针表(Page Directory Pointer Table) |
| 29:21 | PD 索引 | 第 3 级 | 页目录表(Page Directory) |
| 20:12 | PT 索引 | 第 4 级 | 页表(Page Table) |
| 11:0 | 页内偏移 | — | 直接拼接物理地址 |
一次完整的页表遍历需要 4 次内存访问(每级页表一次),再加上最终的数据访问,总共 5 次内存访问。这会导致巨大的性能开销。
2.2 TLB:页表遍历的硬件缓存
TLB(Translation Lookaside Buffer,转译后备缓冲器)是 CPU 内部的一个专用硬件缓存,用于存储最近使用的虚拟地址到物理地址的映射关系。它的核心作用是避免重复的页表遍历,将多次内存访问降为一次。
TLB 的本质:一个全关联或组关联的 CAM(内容可寻址存储器),以虚拟地址的页号(VPN)作为查找键,直接输出物理页帧号(PFN)和页属性(权限、缓存策略等)。
TLB 加速地址转换的流程如下:
- TLB 查找:CPU 发出虚拟地址,MMU 首先在 TLB 中查找 VPN。
- TLB 命中(Hit):直接返回 PFN,拼接页内偏移得到物理地址,零内存访问。
- TLB 未命中(Miss):MMU 触发硬件页表遍历(或软件异常),从内存中逐级读取页表,获取映射关系。
- TLB 填充:将新映射写入 TLB,供后续访问使用。
| 场景 | 内存访问次数 | 延迟(典型) | 说明 |
|---|---|---|---|
| TLB 命中 | 1 次(数据访问) | 1-2 个时钟周期 | 地址转换无额外开销 |
| TLB 未命中(硬件遍历) | 5 次(4 次页表 + 1 次数据) | 数十到数百个时钟周期 | 现代 x86 由硬件自动完成遍历 |
| TLB 未命中(软件遍历) | 更多(需处理 TLB Miss 异常) | 数百到上千个时钟周期 | 常见于 MIPS、早期 SPARC |
2.3 TLB 的层次结构与多级 TLB
现代高性能 CPU 通常实现多级 TLB,类似于 Cache 的 L1/L2 层次结构,以平衡访问速度与容量。
| TLB 级别 | 典型容量 | 关联度 | 访问延迟 | 典型用途 |
|---|---|---|---|---|
| L1 TLB(指令/数据分离) | 32-128 项 | 全关联或 4-8 路组关联 | 1 个时钟周期 | 最频繁访问的映射 |
| L2 TLB(统一) | 512-2048 项 | 4-8 路组关联 | 2-5 个时钟周期 | L1 TLB 未命中的后备 |
| L3 TLB(部分大型处理器) | 4096 项以上 | 8-16 路组关联 | 10-20 个时钟周期 | 大型工作集的映射缓存 |
重要区分:TLB 与数据 Cache 不同。TLB 缓存的是地址映射关系(VPN→PFN),而数据 Cache 缓存的是实际数据内容。两者在 MMU 中的工作阶段不同:TLB 在地址转换阶段,Cache 在数据访问阶段。
2.4 TLB 项结构:不仅仅是地址映射
每个 TLB 项(TLB Entry)不仅包含 VPN 和 PFN,还包含多个属性位,用于控制页面的访问行为和缓存策略。
TLB Entry 典型结构(x86-64 4KB 页):
+----------------+----------------+----+----+----+----+----+----+----+
| VPN (36位) | PFN (36位) | G | P | R | W | X | U | A |
+----------------+----------------+----+----+----+----+----+----+----+
| 虚拟页号 | 物理页帧号 | 全局 | 存在 | 读 | 写 | 执行 | 用户 | 访问 |
+----------------+----------------+----+----+----+----+----+----+----+
| + 其他属性:D(脏位)、PAT(页属性表)、PCD(页缓存禁用)、PWT(页写透)等 |
+-----------------------------------------------------------------------+
关键属性位说明:
- G(Global):全局页,在进程切换时不清除(如内核映射)。
- P(Present):页面是否在物理内存中,为 0 时触发缺页异常。
- R/W/X:读、写、执行权限控制。
- U(User/Supervisor):用户态/内核态访问权限。
- A(Accessed):页面是否被访问过,用于页面置换算法。
- D(Dirty):页面是否被写过,用于写回策略。
2.5 TLB 一致性问题的根源
TLB 是页表内容的硬件缓存。当操作系统修改页表(如解除映射、更改权限、页面迁移)时,TLB 中缓存的旧映射与内存中的新页表之间出现不一致。如果不刷新 TLB,后续访问可能使用错误的映射,导致数据损坏或安全漏洞。
核心矛盾:页表由软件(操作系统)管理,TLB 由硬件(MMU)管理。软件修改页表后,必须通过显式的 TLB 刷新指令(如 x86 的
INVLPG、INVPCID)通知硬件使失效的 TLB 项。
多核系统中,每个 CPU 核心拥有独立的 TLB。一个核心修改页表后,必须确保所有核心的 TLB 都得到刷新,这就是多核 TLB 一致性问题的由来,也是后续章节的核心内容。
2.6 本章小结
- 页表遍历是多级索引查找过程,x86-64 4KB 页需要 4 次内存访问,开销巨大。
- TLB 是页表遍历的硬件缓存,将地址转换延迟从数百时钟周期降低到 1-2 个时钟周期。
- 多级 TLB(L1/L2/L3)进一步优化了容量与速度的平衡。
- TLB 项不仅包含地址映射,还包含权限、缓存策略等关键属性。
- TLB 一致性问题的根源在于:软件修改页表后,硬件 TLB 中的旧映射未同步失效,这是多核系统中必须解决的核心挑战。