numactl --hardware仅显示ACPI SLIT表中的标称延迟(单位10ns),非实测值;真实跨节点延迟需用numactl绑定+mbw或stream实测,因受内存控制器、QPI/UPI链路负载及页表映射动态影响。

最直观的办法,当然是先看 numactl --hardware 里给出的节点间延迟值。不过要注意,这个数更多只是静态标称;真要判断实际延迟,还是得配合 numactl --membind 和 mbw 或 stream 做实测。原因也不复杂:NUMA 跨节点访问的真实开销,并不只由拓扑决定,还会同时受到内存控制器、QPI/UPI 链路负载以及页表映射方式的影响。只盯着硬件拓扑图看,结论很容易跑偏。
用 numactl 查看 NUMA 节点拓扑和标称延迟
系统启动时内核会从 ACPI SLIT 表读取节点间访问延迟(单位为 10ns),numactl --hardware 显示的是这个预设值,不是实测结果。
numactl --hardware中node distances:下的矩阵,比如node 0: 10 21表示 node 0 访问自身内存延迟为 100ns,访问 node 1 内存标称为 210ns- 这个值在 BIOS/UEFI 中可调(如 Intel 的 “Node Interlea ving” 开关),但多数服务器默认关闭,此时 SLIT 表才有效
- 如果输出里没有
node distances,说明固件未提供 SLIT 表,或内核没启用 CONFIG_ACPI_NUMA —— 此时该命令无法反映跨节点延迟
用 mbw 测量跨节点内存带宽与隐含延迟
mbw 不直接报延迟,但通过写入速度反推访问效率:相同大小 buffer,在跨节点分配时带宽下降越明显,说明延迟+竞争开销越大。
- 先绑定到 node 0 并在 node 1 分配内存:
numactl --cpunodebind=0 --membind=1 mbw -n 10 1024 - 对比同节点测试:
numactl --cpunodebind=0 --membind=0 mbw -n 10 1024 - 若跨节点带宽跌到同节点的 40% 以下(如 DDR4 系统中从 25GB/s 降到 10GB/s),基本确认存在显著延迟惩罚,不只是带宽瓶颈
- 注意:mbw 默认用 memset,对缓存友好;加
-a参数启用随机访问模式(mbw -a -n 10 1024)更能暴露 TLB 和页表遍历延迟
用 stream 测试真实访存延迟敏感场景
stream 的 Copy、Scale、Add、Triad 四个 kernel 对内存访问模式不同,其中 Triad(a[i] = b[i] + scalar * c[i])最考验跨 NUMA 节点的数据拉取能力,其带宽衰减直接关联延迟抖动。
- 编译后运行:
numactl --cpunodebind=0 --membind=1 ./stream - 重点看 Triad 结果:若比
--membind=0低 3 倍以上,且Copy下降不明显,说明问题出在多路数据源并发拉取时的远程内存仲裁延迟,而非单纯带宽不足 - stream 不输出 ns 级延迟,但它的 MFLOPS 值在跨节点时剧烈波动(标准差 >15%),就是延迟不稳定的信号
- 配合
perf stat -e cycles,instructions,cache-misses一起跑,能确认是否因远程 cache miss 导致 cycle/stall 暴增
为什么不能只信 /sys/devices/system/node/node*/distance?
这个文件内容来自同一份 SLIT 表,但它只反映“理想路径”下的标称延迟,而真实延迟取决于当前 QPI/UPI 链路是否被其他 CPU 核心或 PCIe 设备占满。
- 同一节点内两个 CPU socket 之间(如 AMD EPYC 的 CCD 间)可能比跨节点延迟还高,但
/sys/.../distance不体现这种微架构细节 - 当启用内存热插拔或大页(
transparent_hugepage=always)时,页表层级变化会让跨节点访问的实际延迟浮动 ±50ns,SLIT 表完全无法覆盖 - 某些厂商(如部分 ARM 服务器)根本没实现 SLIT 表,
numactl --hardware显示所有距离为 10,但实测跨节点延迟可达本地的 8 倍
真实跨核心内存访问延迟从来不是固定值,它随负载、页表状态、链路拥塞实时变化。想靠一个命令“查出延迟”,不如用 mbw 和 stream 在业务负载下持续采样——毕竟你真正关心的,是应用跑起来以后,那一行 memcpy 到底卡不卡。