用途:面向底层开发教学,讲解 CPU 存储层次结构,包括缓存层级、相联度、缓存行大小、一致性协议、伪共享与预取行为,与 cpu-cache-opt 的优化实践互补。
适用场景:解释为何填充(padding)能修复扩展性问题;为多核选择结构体布局;解读缓存未命中计数器;理解嵌入式 SoC 上 DMA 与 CPU 缓存的关系。
主要内容:
- 层次结构:寄存器、每核 L1d/L1i(约 32 KiB、约 4 周期)、每核 L2(约 256 KiB–1 MiB)、共享末级 L3(MiB 至数十 MiB)、DRAM(数百周期)、存储/NUMA 远端(更慢)。嵌入式 MCU 可能只有紧耦合内存,无 L2/L3。
- 缓存行与相联度:x86/ARM64 常见 64 字节行,可用 getconf LEVEL1_DCACHE_LINESIZE 验证;组相联中行映射到一个组并在路内竞争,冲突未命中源于多个别名落入同组。
- 伪共享:同一缓存行上的多个原子变量会互相干扰,需按缓存行对齐填充,如 alignas(64) 与 pad。
- 一致性:MESI 的 Modified、Exclusive、Shared、Invalid 状态,写操作会令其他核心的副本失效,这是原子操作与锁导致缓存行来回传递的原因。
- 预取:可用 __builtin_prefetch 手动预取,硬件步长预取器能识别顺序访问,随机访问则未命中。
- 测量:perf stat -e cache-references,cache-misses,L1-dcache-load-misses ./app。
常见问题与排查:扩展性崩溃多因伪共享,按行对齐每线程数据;LLC 未命中高因工作集超过缓存,可分块算法并做 NUMA 绑定;DMA 不一致需在 MCU 上刷新/失效缓存、Linux 上用 dma_sync;预取反而变慢时移除手动预取;结构体拷贝巨大因 AoS 冷行,可改 SoA。
限制:资料给出的是典型桌面/服务器数值与一般性方法,具体微架构参数需实测确认;未提供安装命令与费用信息。