直接回答:NUMA(非统一内存访问)架构下,内存按 CPU socket 划分成若干 node,CPU 访问本地 node 的内存走直连控制器,访问远端 node 要跨互联总线(Intel UPI、AMD Infinity Fabric),延迟可高出 50% 以上,带宽也打折。
展开解析:Linux 默认采用 first-touch 策略:页由哪个线程首次触碰分配,就落在那个线程所在 node。风险是分配与计算长期错位——比如主线程一次性初始化了全部数据,随后工作线程都在别的 node 上跑,大量访问跨 node。内核的 numa_balancing 特性会周期性扫描,迁移页和线程让它们靠近,但扫描本身有开销,对延迟敏感业务反而成了抖动来源,常被关闭后改用手工策略。
实践要点:numactl --hardware 看拓扑和空闲量,numastat 看各 node 的命中/未命中,numa_miss 持续偏高说明跨 node 访问多。部署上用 numactl --cpunodebind=0 --membind=0 绑核绑内存;MySQL 这类单进程大内存应用则常用 --interleave=all 把页均匀铺到所有 node,避免单个 node 耗尽提前触发 swap 或 OOM。虚拟化场景还要确认 vCPU/内存的 NUMA 拓扑是否正确透传给 Guest。
追问方向:NUMA 对线程绑核策略有什么要求?什么场景 interleave 比 bind 更合适?如何通过 /proc//numa_maps 定位某个进程的跨 node 访问?