土法炼钢兴趣小组的算法知识备份

【操作系统百科】NUMA 内存

文章导航

分类入口
os
标签入口
#numa#mempolicy#autonuma#cxl#numactl

目录

多路(multi-socket)服务器上,每个 CPU socket 挂接本地 DRAM;线程访问本地 node远端 node 的延迟、带宽并不相同——这就是 NUMA(Non-Uniform Memory Access)。忽略拓扑时,常见症状不是「算力不够」,而是 跨 node 内存流量放大、尾延迟抖动、numa_miss 计数攀升;具体倍数取决于 CPU 代际、互连(Intel UPI / AMD Infinity Fabric)与工作集,本文不写入未在本机实测的纳秒级延迟表

单机单 node 环境(例如云主机只暴露一个 NUMA node)仍应会读拓扑:远端访问问题不会出现,但 mempolicy、AutoNUMA 与容器 topology-manager 的配置语义相同——误绑 policy 照样会在多 node 机器上踩坑。

一、先看图

flowchart LR
    C0["CPU socket 0<br/>Node 0"] --> M0["Local DRAM<br/>Node 0"]
    C1["CPU socket 1<br/>Node 1"] --> M1["Local DRAM<br/>Node 1"]
    C0 -.interconnect.-> M1
    C1 -.interconnect.-> M0
    CXL["CXL device"] -.CXL.mem.-> M2["CXL memory<br/>Node 2"]
    classDef local fill:#3fb95022,stroke:#3fb950,color:#adbac7;
    classDef remote fill:#f0883e22,stroke:#f0883e,color:#adbac7;
    classDef cxl fill:#a371f722,stroke:#a371f7,color:#adbac7;
    class C0,C1,M0,M1 local
    class CXL,M2 cxl

二、学术谱系与 Linux 落点

阶段 代表 work 相对前一代
1970s–1980s 共享总线 SMP 内存延迟近似均匀
1990s Dash / DASH(Lenoski et al., ISCA 1992 等) 显式 distributed shared memory,远端访问代价入模型
1990s–2000s SGI Origin、早期 x86 多路 商用 NUMA 机器;OS 需感知 node
2000s+ Linux 2.6+ mempolicy、ACPI SRAT/SLIT 内核调度与分配按 node 拓扑
2010s AutoNUMA(Rik van Riel, 2012) 运行时根据 fault 迁移页/任务
2020s CXL.mem 热插拔、memory tiering(Linux 6.1+) 多于两级 的延迟层次

工程间隙:论文与教材常用 node distance 矩阵(ACPI SLIT)描述相对代价,但 distance 10/21/31 是归一化权重,不是可直接当纳秒用的线性标尺。Intel / AMD 白皮书中的「本地 vs 远端带宽比」也随代际变化——调优应看 numastat / perf 的 node-miss 计数与工作集,而不是背诵固定 ns 数字。

三、拓扑发现(本机可执行)

下列命令在撰写环境(Linux 6.8.0-90-generic,2 vCPU,单 NUMA node)下实际执行;输出经删减,只保留与 NUMA 相关的行。

lscpu | grep -E 'NUMA|Socket|CPU\(s\)|Model name'
numactl --hardware
CPU(s):                               2
Model name:                           AMD EPYC 9754 128-Core Processor
Socket(s):                            1
NUMA node(s):                         1
NUMA node0 CPU(s):                    0,1
---
available: 1 nodes (0)
node 0 cpus: 0 1
node 0 size: 1935 MB
node 0 free: 89 MB
node distances:
node   0
  0:  10

如何读

补充工具:lstopo(hwloc)可视化 socket / core / NUMA 关系;容器场景还需读 cgroup 与 Kubernetes topology-manager 策略。

四、mempolicy

Linux 给每个进程 / VMA 一套内存分配策略(Documentation/admin-guide/mm/numa_memory_policy.rst):

# 绑定 node 0
numactl --membind=0 ./app

# 交错分配
numactl --interleave=all ./app

代码级

#include <numaif.h>
set_mempolicy(MPOL_BIND, nodemask, maxnode);

// per-VMA
mbind(addr, len, MPOL_BIND, nodemask, maxnode, MPOL_MF_MOVE);

五、AutoNUMA / NUMA balancing

5.1 问题

手动 numactl 粒度粗——进程运行中可能被调度器迁到远端 CPU,或 fork 后子进程在远端 node 跑却用本地内存。

5.2 AutoNUMA 方案

内核定期把 PTE 标为不可访问(PROT_NONE)→ 触发 NUMA hint fault → 记录访问 node → 若页与任务不同 node → migrate page 或 migrate task(Rik van Riel, AutoNUMA, 2012)。

cat /proc/sys/kernel/numa_balancing
cat /proc/vmstat | grep numa
# numa_hit    numa_miss    numa_foreign
# numa_pages_migrated

注意kernel.numa_balancing 并非所有发行版默认 1——撰写环境为 0(单 node 上 AutoNUMA 收益有限)。多 socket 生产机应 以实际 /proc/sys/kernel/numa_balancing 为准,再结合 numa_miss 决定是否关闭。

5.3 代价

NUMA hint fault 有 CPU 开销;对 I/O 密集不明显,对计算密集曾有 约 1–3% CPU 量级的报告(Red Hat / LWN 讨论,随工作集变化大)。大堆 Java 服务若出现周期性 fault 毛刺,可尝试 numa_balancing=0 并改用手动 numactl / -XX:+UseNUMA

六、page migration

内核可在 node 间迁移物理页:

migrate_pages(pid, old_nodes, new_nodes);  // syscall

或用户态 migratepages 工具。步骤:目标 node 分配 → 复制 → rmap 更新 PTE → 释放源页;大批量迁移可达毫秒级停顿,需与业务 SLA 对齐。

七、NUMA 与调度

多核负载均衡 已讲调度器的 NUMA 感知,此处只列交叉点:

八、CXL 与分级 NUMA

CXL(Compute Express Link)可把远端 DRAM 或持久内存挂成 新的 NUMA node。Linux 6.x+ 支持 CXL memory hotplug 与 memory tieringDocumentation/admin-guide/mm/memory-tiers.rst):热页留在快层,冷页 demote 到慢层(CXL node)。

# 若内核启用了 tier 框架(多 node 机器上才有意义)
ls /sys/devices/system/node/

CXL 节点的 绝对延迟 随设备与拓扑变化;调优应结合 tier 统计与 numastat,而非固定「~200ns」类口号。

九、生产调优

9.1 数据库

# MySQL / PostgreSQL:buffer pool 被所有 CPU 访问时,常见做法
numactl --interleave=all mysqld
# 或 membind 配合 CPU 绑定

interleave 的逻辑是 避免单 node DRAM 带宽成为瓶颈;若工作集明显小于单 node 容量,membind + CPU 绑定 往往更优——需用 numastat 验证 numa_miss

9.2 JVM

numactl --localalloc java -Xmx32g ...
# 大堆可评估 -XX:+UseNUMA(G1/ZGC 与版本相关)

9.3 HPC

mpirun --map-by numa --bind-to core ./simulation

9.4 容器

Kubernetes topology-managerTopologyPolicy: best-effort / restricted / single-numa-node)尽量保证 Pod 的 CPU 与内存在同一 node。

十、诊断

撰写环境执行 numastat(节选):

                           node0
numa_hit             17958575334
numa_miss                      0
numa_foreign                   0
local_node           17958420591
other_node                     0

单 node 上 numa_miss / other_node 为 0 是预期;多 node 机器上若 numa_foreignnuma_miss 持续偏高,应排查 mempolicy、绑核与 buffer 分配策略。

常用命令:

numastat
numastat -p <pid>

perf stat -e node-loads,node-load-misses,node-stores,node-store-misses ./app

cat /proc/$$/numa_maps

十一、常见问题

A:MySQL 性能波动大
buffer pool 全部分配在进程启动时的 node,而查询线程跑在另一 socket → numa_miss 上升。修复:numactl --interleave=all 或 membind + 绑核。

B:NUMA balancing 导致 CPU 毛刺
大内存服务 hint fault 频繁 → 可 numa_balancing=0 并手动绑定。

C:CXL 节点意外参与 default 分配
检查 memory tier / demotion 配置与 mpol;确认慢层 node 是否应 bind 为冷数据专用。

十二、开放问题

  1. AutoNUMA vs 显式绑定的默认策略:内核/community 尚未给出适用于所有 workload 的默认开关——数据库、HPC、容器混部场景结论相反;仍依赖 numastat + 业务 SLA 做 A/B。
  2. 多于两级的 memory tiering:CXL + 本地 DDR + 远端 socket 三层并存时,demotion 策略与 应用透明性 仍在快速演进(Linux 6.x 框架 vs 用户态 tiering 库)。
  3. Disaggregated memory 与调度:当计算 node 几乎无本地 DRAM(分离式 OS 趋势),CFS 的 NUMA 代价模型是否足够——sched_ext 能否接入可编程内存距离,是 OS 研究活跃方向,生产默认路径尚未统一。

十三、小结


参考资料

规范与内核文档(A 级)

论文与报告(A 级 / B 级)

源码(A 级)

工具与站内


上一篇OOM Killer 下一篇HugeTLB 与 THP

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-07-09 · os / architecture

【操作系统百科】可拆分 OS

CXL 内存池化如何动摇 OS 对本地 DRAM 的假设?从资源解耦、CXL.mem 语义、LegoOS/PhantomOS/Twilight 学术原型,到 Linux CXL 驱动、dax、HMM 与 memory tiering,说明 disaggregated OS 的工程边界与 NUMA 演进。

2026-07-10 · os / architecture

【操作系统百科】OS 的下一个十年

综合 Windows/RTOS/Unikernel/Rust/机密计算/CXL 等前沿篇章,从 Rust 内核、机密计算、可拆分内存、io_uring 统一 I/O、eBPF 可编程内核五条趋势出发,按现在/三年/十年框架说明应用开发者应调整的假设与可执行建议。

2026-05-26 · os

【操作系统百科】spinlock 家族

内核 spinlock 从关中断到 qspinlock 演化了四代。本文讲原始 spinlock、ticket lock、MCS lock、qspinlock、paravirt qspinlock、spin_lock_irqsave 的代价与 NUMA 友好性。

2026-05-19 · os

【操作系统百科】epoll 内部

epoll 用红黑树管理 fd、就绪链表 O(1) 返回事件——打败 select/poll 的关键。本文讲 eventpoll 结构、LT/ET 语义、EPOLLEXCLUSIVE 与惊群、级联 epoll、EPOLLONESHOT、与 io_uring 的比较。


By .