[MMU]TLB Miss 后的 Hardware Table Walk及优化
TLB Miss 后的 Hardware Table Walk及优化
摘要:基于x86-64架构(Intel/AMD的64位模式)来解释,因为这是4级页表(PML4/PDP/PD/PT)最常见的实现场景。如果您指的是其他架构(如ARM64或RISC-V),流程类似但细节不同,请提供更多信息,我可以调整。
响应假设4KB页大小(标准情况),并聚焦于硬件table walk(由CPU的MMU - Memory Management Unit自动执行)。我会逐步描述过程,包括硬件的内部操作、地址计算和异常处理。
1. 背景:TLB Miss 和 Hardware Table Walk 简介
- TLB (Translation Lookaside Buffer):这是一个高速缓存,存储最近使用的虚拟地址(VA)到物理地址(PA)的映射。如果CPU需要访问一个VA,首先查询TLB:
- TLB Hit:直接获取PA,快速完成地址转换(通常几周期)。
- TLB Miss:映射不在TLB中,触发table walk。
- Hardware Table Walk:在现代x86-64 CPU中,这是由硬件(MMU)自动执行的“行走”过程。MMU会遍历多级页表,从CR3寄存器开始,逐级读取页表条目(entries),直到找到对应的物理页帧地址或触发异常。
- 为什么硬件执行?:为了效率,x86-64使用硬件walk(不像一些旧架构如MIPS依赖软件walk)。整个过程发生在CPU内部,可能涉及内存总线访问(慢于TLB hit)。
- 触发时机:指令获取(fetch)、数据加载/存储时发生TLB miss。
- 持续时间:可能需要多次内存访问(每个级1次),总计10-100+周期,取决于缓存命中。
- 优化:现代CPU有Page Walk Cache (PWC) 或TLB预取来加速。
如果walk成功,MMU会将结果插入TLB;如果失败,触发page fault异常交给OS处理。
2. 硬件进行 Table Walk 的详细过程
硬件table walk从CR3寄存器开始,逐级遍历4级页表。每个级涉及:
- 计算条目地址(使用VA的索引位)。
- 通过内存总线读取条目(64位)。
- 检查标志位(如Present位)。
- 提取下一级表的物理基地址(base address)。
假设一个48位虚拟地址(VA),分解为:
- Bits 47-39: PML4索引。
- Bits 38-30: PDP索引。
- Bits 29-21: PD索引。
- Bits 20-12: PT索引。
- Bits 11-0: 页内偏移。
步骤1: 初始化和访问PML4(第1级页表)
- 起点:MMU读取CR3寄存器,获取PML4表的物理基地址(PML4_Base,通常对齐到4KB,低12位为0)。
- CR3还包含控制位,如PCD(Page Cache Disable)和PWT(Page Write-Through),影响缓存行为。
- 计算PML4 Entry (PML4E)地址:
- Index = VA[47:39](9位)。
- PML4E_PA = PML4_Base + (Index << 3)(每个条目8字节)。
- 硬件操作:
- MMU发出内存读取请求到PML4E_PA(通过L1/L2/L3缓存或主存)。
- 读取64位PML4E。
- 检查和提取:
- 检查Present (P)位(bit 0):如果P=0,触发page fault(#PF异常,vector 14)。
- 检查权限位(如U/S - User/Supervisor, R/W - Read/Write):如果当前模式(用户/内核)或操作(读/写)不匹配,触发#PF。
- 如果有效,从PML4E的bits 51-12提取PDP表的物理基地址(PDP_Base)。
- 缓存优化:如果PML4E在Page Walk Cache中命中,跳过内存读取。
步骤2: 访问PDP(第2级页表)
- 计算PDP Entry (PDPE)地址:
- Index = VA[38:30](9位)。
- PDPE_PA = PDP_Base + (Index << 3)。
- 硬件操作:
- MMU读取PDPE_PA(内存访问)。
- 读取64位PDPE。
- 检查和提取:
- 检查P位:如果0,#PF。
- 检查权限位。
- 检查Page Size (PS)位(bit 7):如果PS=1,这是1GB大页(huge page)。
- 直接计算PA:PA = (PDPE[51:30] << 30) + VA[29:0](低30位偏移)。
- Walk结束,跳到步骤5。
- 如果PS=0,从PDPE的bits 51-12提取PD表的物理基地址(PD_Base)。
步骤3: 访问PD(第3级页表)
- 计算PD Entry (PDE)地址:
- Index = VA[29:21](9位)。
- PDE_PA = PD_Base + (Index << 3)。
- 硬件操作:
- MMU读取PDE_PA。
- 读取64位PDE。
- 检查和提取:
- 检查P位:如果0,#PF。
- 检查权限位。
- 检查PS位:如果1,这是2MB大页。
- 直接计算PA:PA = (PDE[51:21] << 21) + VA[20:0](低21位偏移)。
- Walk结束,跳到步骤5。
- 如果PS=0,从PDE的bits 51-12提取PT表的物理基地址(PT_Base)。
步骤4: 访问PT(第4级页表)
- 计算Page Table Entry (PTE)地址