别让你的内存跑马拉松

📅 2026/7/8 6:04:21 👁️ 阅读次数 📝 编程学习
别让你的内存跑马拉松

别让你的内存跑马拉松

1. 问题

多路服务器上,CPU 和内存不在同一个节点时,每次访问多走一条跨节点总线。

延迟翻倍,带宽打折。这就是你 128 核跑不过 64 核的原因。

随机分配绑定本地节点
延迟~200ns~80ns
带宽跨节点总线(共享)本地内存(独享)

2. Take Away

内存分配不是"给一块空间",而是"给一块空间 + 决定它在哪"。

malloc只做了前半件事。后半件事要用mbind(MPOL_BIND)把物理页钉到目标节点。

3. 怎么做

auto&rm=umpire::ResourceManager::getInstance();autonodes=umpire::numa::get_host_nodes();autonode0=rm.makeAllocator<umpire::strategy::NumaPolicy>("node0",rm.getAllocator("HOST"),nodes[0]);void*ptr=node0.allocate(size);// 数据自动在 Node 0

位置不对?一行搬过去:

rm.move(ptr,node0);// 指针不变,物理页瞬移

4. 三条规律

  1. 先 malloc 后 mbind— 预留地址空间,再绑定物理页。指针地址不变,业务代码不用改。
  2. move 是原地操作— VA 不变,PA 变。迁移完了指针还是那个指针。
  3. 同一个 move API,Host NUMA 和 GPU 都能用— 局部性问题在不同尺度上是同一件事。

5. 验证

numactl--hardware# 看拓扑umpire::numa::get_location# 看位置perfstat-enuma_miss# 看效果