缓存与 NUMA 局部性
更新时间:2026-10-01。多核缓存的局部性原则在多插槽系统上扩展为 NUMA:就近内存快、跨路慢。
本文要回答的问题
- 本地和远端内存差距有多大,慢在哪?
- 内存页“归属”由什么决定?
一、本地/远端差异
每个 socket 有本地内存,访问另一 socket 的内存要经 socket 间互联并查跨路一致性目录,延迟更高、可用带宽更低、还可能争抢互联。对延迟敏感负载,远端访问常是隐形大坑。
二、归属与控制
Linux 用首次触碰(first-touch)决定页分配在哪个节点;线程在一个 socket 跑却由另一 socket 线程初始化数据,就会产生远端访问。用绑核 + 本地分配(numactl)、让生产者线程就地初始化数据来保持局部性。
三、常见坑
- 主线程一次性初始化全部数组,工作线程全变远端访问。
- 调度器迁移线程离开原节点。
- 只看总容量不看节点局部性。
小结
NUMA 把缓存局部性扩展到内存节点,跨 socket 访问延迟高;靠 first-touch 本地分配和绑核维持局部性。下一篇 缓存功耗与能耗。
总结
多 socket 系统把缓存的局部性原则延伸到了内存:每个 socket 有本地内存,跨 NUMA 访问要经过 UPI/Infinity Fabric 互联、查询跨 socket 一致性目录,延迟更高、可用带宽更低;Linux 按首次触碰(first-touch)决定页归属,主线程统一初始化、工作线程异地访问是最常见的远端访问陷阱,要用绑核 + numactl 本地分配、让生产者就地初始化来规避。总内存容量够不等于性能够——数据在哪个节点,比数据有多少更重要。