NUMA架构将系统划分为多个节点,每个节点含CPU核心组、本地内存、内存控制器及I/O域,本地访问延迟低,远程访问需经UPI/Infinity Fabric链路,延迟为本地2–3倍、带宽下降。

物理内存拓扑不是“一块大内存”的线性视图,而是由 NUMA 节点、CPU 绑定关系、本地/远程访问代价共同构成的立体结构。直接看 /proc/meminfo 或 free 只能得到总量和剩余量,完全无法反映真实布局。
用 numactl --hardware 看硬件级 NUMA 拓扑
这是最接近 BIOS/UEFI 实际探测结果的命令,输出反映的是内核初始化时读取的硬件拓扑,不随运行时变化:
-
available: N nodes表示物理 NUMA 节点总数,注意:BIOS 关闭 NUMA 后它仍可能显示多个节点,需结合dmesg | grep -i numa确认内核是否真正启用 -
node X cpus:列出绑定到该节点的所有逻辑 CPU 编号(如0-7,16-23),不是物理核心编号 -
node X size:是该节点本地内存总量(KB),但不等于/proc/meminfo中的 MemTotal —— 因为部分 RAM 可能被 firmware 保留或 early-reserve -
node distances:对角线应为最小值(通常 10),非对角线若 ≥30,说明跨节点访问开销显著;此时盲目用numactl --cpunodebind绑核反而可能降低性能
查 /sys/devices/system/node/ 看运行时节点状态
这个路径是内核暴露的实时 NUMA 运行态接口,所有文件内容会随内存回收、进程迁移、页面迁移动态更新:
-
/sys/devices/system/node/node0/meminfo包含该节点每类内存页(如 Active(file)、Inactive(anon))的精确计数,比numactl --hardware更细粒度 -
/sys/devices/system/node/node0/cpulist显示当前可调度到该节点的 CPU 列表——它可能与numactl --hardware输出不同,因为内核可能已 offline 部分 CPU -
/sys/devices/system/node/node0/下的distance文件内容与numactl --hardware中的 node distances 一致,但它是只读运行时快照 - 如果某节点
meminfo中MemFree极低,而其他节点仍有大量空闲,大概率是应用未启用interleave或错误绑定了节点,导致内存分配局部化
结合 lscpu -e 确认 CPU 与 NUMA 节点映射
lscpu -e 输出每行一个逻辑 CPU,并列展示其所属 SOCKET、CORE、NODE,是验证 CPU 是否按预期归属 NUMA 的关键工具:
- 执行
lscpu -e=CPU,SOCKET,CORE,NODE,观察 NODE 列是否与numactl --hardware中的节点划分一致 - 若发现同一 SOCKET 下的多个 CORE 分属不同 NODE,说明 BIOS 启用了 Sub-NUMA Clustering(SNC)模式,此时
lscpu显示的节点数会虚高,应以numactl --hardware为准 - 虚拟机中该命令不可靠:Hypervisor 可能伪造拓扑,
lscpu | grep "Hypervisor"非空时,必须回宿主机查numactl --hardware - CACHE 列在虚拟机里基本无效,L3 共享关系常被抽象掉,不能用于缓存亲和性调优
别漏掉 /proc/iomem 中的物理地址断点
/proc/iomem 是内核视角下物理地址空间的运行时切片,能揭示 System RAM 是否连续、是否存在被 firmware 或 kernel 预留的空洞:
- 只认顶层未缩进且含
System RAM的行,例如80000000-9effffff : System RAM,缩进的子区域(如 PCI Bus 下的设备)不算可用内存 - 多段
System RAM表明物理内存不连续,常见于 UEFI 启动系统或有大量 PCIe 设备的服务器 - 若某段
System RAM在/proc/iomem中缺失,但在dmesg | grep e820中存在,说明该段被内核 early-reserve、kdump 预留或 firmware 保留了 -
/proc/iomem不提供任何内存使用状态,它只告诉你“哪些物理地址范围属于 RAM”,和/proc/meminfo完全不重叠
真正难的是交叉验证:当 numactl --hardware 显示节点 0 有 32GB 内存,/sys/devices/system/node/node0/meminfo 却长期 MemFree 低于 1GB,而 lscpu -e 又显示大量 CPU 归属该节点——这时得查进程的 numastat 或 /proc/PID/status 中的 Mems_allowed,否则光看拓扑永远定位不到内存分配卡点。


















