分页机制因需要访问内存中的页表而带来巨大的性能开销。TLB(Translation-Lookaside Buffer) 作为地址转换的硬件缓存,是解决这一问题的核心。
核心问题如何利用 TLB 加速地址转换?在 TLB 未命中时,硬件与操作系统如何高效协作?
TLB 基本原理
TLB 是 MMU 的一部分,缓存了频繁使用的虚拟到物理地址的映射。
1. 算法流程
硬件首先在 TLB 中查找 VPN:
- TLB 命中:直接获取 PFN,速度极快(接近 CPU 频率)。
- TLB 未命中:访问内存页表,更新 TLB,并重试指令。
VPN = (VirtualAddress & VPN_MASK) >> SHIFT
(Success, TlbEntry) = TLB_Lookup(VPN)
if (Success == True) { // TLB Hit
if (CanAccess(TlbEntry.ProtectBits) == True) {
Offset = VirtualAddress & OFFSET_MASK
PhysAddr = (TlbEntry.PFN << SHIFT) | Offset
AccessMemory(PhysAddr)
} else {
RaiseException(PROTECTION_FAULT)
}
} else { // TLB Miss
PTEAddr = PTBR + (VPN * sizeof(PTE))
PTE = AccessMemory(PTEAddr)
if (PTE.Valid == False) {
RaiseException(SEGMENTATION_FAULT)
} else if (CanAccess(PTE.ProtectBits) == False) {
RaiseException(PROTECTION_FAULT)
} else {
TLB_Insert(VPN, PTE.PFN, PTE.ProtectBits)
RetryInstruction() // 重新尝试指令,此时 TLB 已命中
}
}2. 局部性与性能
TLB 的成功源于程序的局部性(Locality):
- 空间局部性:访问数组元素时,后续访问多在同一页内(仅首个元素触发 Miss)。
- 时间局部性:循环变量等数据会被反复访问。

TLB 管理细节
1. 谁来处理未命中?
- 硬件管理 (CISC/x86):硬件自动遍历页表并更新 TLB。
- 软件管理 (RISC/MIPS):硬件抛出异常,由操作系统的陷阱处理程序查找页表并更新 TLB。优势在于灵活性和硬件简单性。
2. 上下文切换
TLB 映射仅对当前进程有效。切换进程时需处理冲突:
- 方案 A:清空 (Flush):切换时将所有有效位置 0,但会导致新进程初期大量未命中。
- 方案 B:ASID (地址空间标识符):在 TLB 项中增加 ASID 字段区分进程,支持跨进程共享 TLB。
| VPN | PFN | 有效位 | ASID |
|---|---|---|---|
| 10 | 100 | 1 | 1 |
| 10 | 170 | 1 | 2 |
3. 替换策略
当 TLB 满时,通常采用 LRU(最近最少使用) 或 随机(Random) 策略来选择替换项。
实际系统示例:MIPS R4000

- 项结构:包含 VPN、PFN、G(全局位)、ASID、C(一致性)、D(脏位)、V(有效位)。
- 管理指令:提供
TLBP、TLBWI等特权指令供 OS 管理。
小结
- 成就:TLB 使虚拟内存性能接近原生物理内存。
- 挑战:TLB 覆盖范围限制了大型程序的性能。
- 对策:采用大页(Huge Pages)或虚拟索引缓存进一步优化。
Culler 定律RAM 不总是 RAM。由于 TLB 缓存的存在,随机访问大范围内存可能导致严重的性能损失。