3. Cache与MMU硬件基础回顾
在TRACE32中定位Cache与MMU相关故障之前,必须先建立对硬件行为的准确认知。很多“看起来像软件Bug”的现象,本质是地址转换或缓存一致性在底层发生了偏差。本节把CPU访问内存的完整路径拆开,从Cache层级、映射方式、页表结构、TLB到地址转换流程逐层梳理,为后续用TRACE32观察寄存器、页表和Cache状态打下基础。
一、Cache层级:L1/L2/L3的分工与访问顺序
现代处理器通常采用多级Cache结构。以典型的ARM Cortex-A系列为例,L1分为指令Cache(I-Cache)和数据Cache(D-Cache),容量小(如32KB或64KB)、访问延迟低(1~4个周期),通常与核心同频。L2为统一Cache(指令与数据共享),容量较大(256KB~1MB),延迟约10~20个周期。L3为多核共享Cache,容量可达数MB,延迟更高但远低于DDR。
CPU发出一个虚拟地址后,硬件按L1→L2→L3→主存的顺序逐级查找。若在某一级命中,则直接返回数据,不再访问下一级;若全部未命中,才从DDR读取,并把数据逐级填充回各级Cache。这个“逐级查找、逐级填充”的顺序,决定了我们在TRACE32中看到的Cache命中率、缺失率以及访问延迟分布。
需要特别注意的是,Cache的分配单位是Cache Line,常见为64字节。即使只读取1字节,硬件也会把该字节所在的整条Cache Line从主存搬入Cache。这一特性直接影响后续对“伪共享”和“Cache一致性”问题的判断。
二、映射方式:直接映射、组相联与全相联
Cache如何决定“主存中的某一块数据应该放在Cache的哪个位置”,由映射方式决定。常见有三种:
- 直接映射:每个主存块只能映射到唯一一个Cache行。硬件简单、查找快,但容易发生冲突缺失——多个主存块争用同一Cache行时会反复替换。
- 全相联:主存块可放入任意Cache行。冲突缺失最少,但需要并行比较所有Tag,硬件成本高,通常只用于小容量TLB或Victim Cache。
- 组相联:折中方案。Cache被分为若干组,每组包含N行(N路),主存块先映射到固定组,再在组内任选一行。例如4路组相联,表示每组有4个可选位置。现代L1/L2普遍采用4~16路组相联。
在TRACE32中查看Cache配置时,常会看到类似“L1 D-Cache: 32KB, 4-way set associative, 64-byte line”的描述。这里的“4-way”就是组相联的路数。理解映射方式,有助于判断某次Cache缺失是容量缺失、冲突缺失还是强制缺失。
三、MMU页表结构:多级页表与地址拆分
MMU(内存管理单元)负责把CPU发出的虚拟地址(VA)转换为物理地址(PA)。转换依据是页表,页表由操作系统在内存中建立,MMU硬件负责遍历。以ARMv8-A的4KB页、48位虚拟地址为例,页表通常为4级:
VA[47:39] → L0索引(9位)
VA[38:30] → L1索引(9位)
VA[29:21] → L2索引(9位)
VA[20:12] → L3索引(9位)
VA[11:0] → 页内偏移(12位,4KB页)
每一级页表项(PTE)中保存下一级页表的物理基地址,最后一级PTE保存最终物理页帧号(PFN)以及权限位(AP)、可执行位(XN)、可缓存位(C)、可缓冲位(B)、访问标志(AF)等。MMU从TTBR寄存器(Translation Table Base Register)取得L0页表基址,逐级读取,最终拼出物理地址。
页表项中的属性位直接决定该页是否可缓存、是否可共享、是否可执行。如果属性配置错误,例如把设备寄存器区域错误地标记为可缓存,就会导致读写外设时数据被Cache缓存,出现“写寄存器不生效”或“读状态永远不变”的典型故障。TRACE32可以通过读取TTBR和遍历页表,直接查看某个虚拟地址对应的PTE内容,这是定位此类问题的关键手段。
四、TLB工作原理与地址转换流程
如果每次地址转换都去遍历4级页表,性能无法接受。因此MMU内部设置了TLB(Translation Lookaside Buffer),用于缓存最近使用过的虚拟页到物理页的映射关系。TLB本质上是一个小容量、全相联或组相联的高速查找表。
完整的地址转换流程如下:
- CPU发出虚拟地址VA。
- MMU用VA的虚拟页号(VPN)查询TLB。
- 若TLB命中,直接得到物理页帧号PFN,与页内偏移拼接成物理地址PA,访问Cache/主存。
- 若TLB未命中,MMU启动页表遍历(Page Table Walk),从TTBR指向的L0页表开始逐级读取PTE。
- 遍历成功后,把新的映射关系填入TLB,再按命中路径完成访问。
- 若遍历过程中发现PTE无效或权限不足,则触发缺页异常(Page Fault)或权限异常,交由操作系统处理。
TLB命中率对性能影响极大。TLB容量有限,当工作集跨越的页数超过TLB覆盖范围时,会发生TLB抖动,表现为地址转换延迟急剧上升。在TRACE32中,可以通过性能计数器观察TLB缺失次数,结合页表遍历路径判断是否存在页表层级过深或页粒度不合理的问题。
五、从硬件行为到TRACE32观察点
理解上述硬件机制后,在TRACE32中定位Cache/MMU故障就有了明确的观察对象。例如:
- 怀疑地址转换错误时,用
MMU.List或MMU.Scan命令遍历页表,查看目标虚拟地址对应的PTE是否有效、权限位是否正确。 - 怀疑TLB未命中导致性能异常时,读取性能计数器中的TLB缺失计数,结合页表遍历深度判断是否因页表层级过多或页粒度太小引起。
- 怀疑Cache一致性问题时,用
Cache.List查看指定地址的Cache状态(是否在Cache中、属于哪一级、是否脏),必要时用Cache.Flush或Cache.Clean观察行为变化。 - 怀疑设备寄存器被错误缓存时,检查对应页的PTE属性位(C/B位),确认是否被标记为可缓存。
这些操作的前提,是清楚知道VA如何拆分成页表索引、TLB如何缓存映射、Cache如何按行填充。本节梳理的层级、映射、页表、TLB和转换流程,正是后续所有TRACE32故障定位动作的硬件基础。