11.6 CPU Cache 与 NUMA

一句话

现代 CPU 的瓶颈不是 “算得慢”,是 “等数据”:L1 命中约 1ns,主存约 60–100ns;NUMA 再把主存分成 “本地/远程”,远程访问再贵 1.5–2 倍——所以高性能代码做的是 “让数据待在缓存里、待在本地节点上”。

层级与量级

层级 延迟(量级) 容量 备注
L1 ~1ns(4 周期) 32–64KB 分指令/数据
L2 ~4ns(12 周期) 256KB–1MB 私有
L3 ~10–20ns 数 MB–数十 MB 多核共享
主存 ~60–100ns GB–TB 跨 NUMA 再 ×1.5–2
SSD ~100μs TB 与 CPU 差 3 个数量级

三个决定性概念

概念 含义 工程动作
缓存行 64B CPU 按行加载;改一个字节要独占整行 让热数据紧凑排列(数组优于链表)
伪共享 两个核改同一行的不同字段,缓存行来回失效 填充(padding)或按核分片
NUMA 内存分节点,跨节点访问更慢 绑核 + 本地分配(numactl)

伪共享的典型现象:多线程计数器各自加 1,吞吐反而比单线程低——它们在同一缓存行上互相打。

观测手段

工具 看什么
perf stat cache-misses、LLC-load-misses、IPC
perf c2c 伪共享与缓存行争用
numastat / numactl -H 跨节点分配比例
lscpu NUMA 节点与缓存拓扑

调度与缓存的关系见 11.1 进程、线程与调度;观测手段见 11.7 eBPF 与内核态观测、15.9 性能剖析工具链 (火焰图 / perf / eBPF)。

落到数字:跨节点与 miss 的代价

访问 延迟量级 相对代价
L1 命中 ~1ns 1×
L3 命中 10–20ns 10–20×
本地内存 60–100ns 60–100×
远程 NUMA 内存 100–200ns 100–200×
伪共享往返 数十–数百 ns 与核数相关
lscpu | grep -iE "numa|socket|cache"      # 拓扑
numastat -p <pid> 2>/dev/null || echo "无 numastat"
perf stat -e cache-misses,LLC-load-misses,instructions ./app

反模式

反模式 后果
用链表/指针跳转遍历热数据 每次跳转都可能 miss,性能差 10 倍
多线程共享一个计数器 伪共享,扩展性归零
容器不绑核、不感知 NUMA 跨节点访问,延迟抖动
盲目开大页 分配停顿;对随机访问才有明显收益

三条铁律

🔑 顺序访问 + 紧凑布局是最高性价比的优化。

🔑 共享可写字段要分片;否则缓存行争用比锁还慢。

🔑 NUMA 上 “内存跟着 CPU 走”;跨节点访问是隐形的 2 倍延迟。

自检

Q1 为什么 “数组遍历” 比 “链表遍历” 快一个数量级?

▸ 答案:因为数组是连续内存,CPU 预取器能提前把后续缓存行拉进来(顺序访问命中率高);链表每次跳转都是随机地址,几乎每跳一次 cache miss(约 100ns)。当元素很小、数据量大时,差距能到 10 倍以上。

Q2 什么是伪共享?怎么消除?

▸ 答案:两个核分别修改同一缓存行内的不同变量,每次写都要把该行置为独占,导致对方的缓存行失效,来回同步。消除方式:把热点字段各自填充到独立的 64B 行(padding),或按核/线程分片计数,最后再汇总。

Q3 numactl --interleave=all 适合什么场景?

▸ 答案:适合访问模式随机、无本地性的负载(如大内存数据库的全表扫描),把内存均匀分布到各节点可避免单节点耗尽。反之,对延迟敏感、数据有局部性的服务,应该用 --cpunodebind + --membind 绑定到同一节点。

Q4 L3 命中率和吞吐是什么关系?

▸ 答案:L3 未命中意味着要访问主存(约 100ns),而 CPU 一个周期不到 1ns——一次 miss 相当于几百个周期的空转。因此 “LLC 命中率下降 10%” 常常对应吞吐下降 20% 以上,尤其在高并发、大工作集的场景。

Q5 为什么虚拟化和容器会影响缓存与 NUMA 表现?

▸ 答案:虚拟机的 vCPU 可能被调度到不同物理核、跨 NUMA 分配内存;容器共享宿主缓存,邻居的 “缓存污染” 会直接影响你的命中率。对策是绑核、限制 CPU 配额、并接受 “共享 L3 是邻居噪声的来源” 这一现实。

Q6 为什么 “核数增加” 有时反而让吞吐下降?

▸ 答案:因为共享资源的争用上升:L3 与内存带宽被更多核分食、伪共享与锁竞争加剧、跨 NUMA 访问比例变高。表现为 “加核后单核效率下降、总吞吐走平甚至下降”。判断看 perf stat 的 IPC 与 LLC miss 率是否同步恶化。

关联