如何在 Linux 系统上禁用 NUMA 节点的内存

use*_*793 6 linux rhel memory numa

有没有办法禁止访问与NUMA机器上的给定 NUMA 节点/套接字关联的内存?

我们与数据库供应商就我们的 HP DL560 机器存在一些争议。DB 销售类型的技术支持人员很高兴我们不能使用我们的 DL560,但不得不购买新的 DL360,因为它们的插槽较少。我相信他们关心的是访问套接字间内存的速度。他们建议,如果我坚持保留 DL560,我应该将两个插座留空。我认为他们错了(又名疯狂)但我需要测试来证明我的立场是稳固的。

我的配置:
机器有四个插槽,每个插槽有 22 个超线程物理内核,总共 176 个表观内核,总共 1.5 T 内存。操作系统为 Red Hat Enterprise Linux Server 7.4 版。

lscpu 显示内容(部分):

$ lscpu | egrep 'NUMA|ore'
Thread(s) per core:    2
Core(s) per socket:    22
NUMA node(s):          4
NUMA node0 CPU(s):     0-21,88-109
NUMA node1 CPU(s):     22-43,110-131
NUMA node2 CPU(s):     44-65,132-153
NUMA node3 CPU(s):     66-87,154-175
Run Code Online (Sandbox Code Playgroud)

如果我可以访问物理硬件,我会考虑从两个插槽中拉出处理器来证明我的观点,但我没有访问权限,无论如何我也无权在硬件上胡闹。

下一个最好的方法是使用操作系统虚拟禁用套接字。我在这个链接上读到我可以让处理器停止服务

echo 0 > /sys/devices/system/cpu/cpu3/online
Run Code Online (Sandbox Code Playgroud)

并且,确实,处理器已停止使用,但这与内存无关。

我刚刚关闭了套接字 #3 的所有处理器(使用 lscpu 查找哪些是用于套接字#3):

for num in {66..87} {154..175}
do
    echo 0 > /sys/devices/system/cpu/cpu${num}/online
    cat /sys/devices/system/cpu/cpu${num}/online
done
Run Code Online (Sandbox Code Playgroud)

并得到:

$ grep N3 /proc/$$/numa_maps
7fe5daa79000 default file=/usr/lib64/libm-2.17.so mapped=16 mapmax=19 N3=16 kernelpagesize_kB=4
Run Code Online (Sandbox Code Playgroud)

其中,如果我没有正确阅读,则显示我当前的进程正在使用套接字 #3 中的内存。除了当我关闭处理器时外壳已经在运行。

我开始了一个新进程,它尽最大努力吞噬内存,

$ cat /proc/18824/numa_maps | grep N3

最初不返回任何记录,但在长时间占用内存后,它开始使用节点 3 上的内存。

我尝试运行我的程序numactl并绑定到节点 0,1,2 并且它按预期工作......除了我无法控制供应商的软件并且 Linux 中没有设置另一个进程set_mempolicy使用的服务numactl

除了物理移除处理器之外,有没有办法强制解决这个问题?

ron*_*ron 3

我相信他们关心的是访问插槽间内存的速度。他们建议,如果我坚持保留 DL560,我应该将其中两个插槽留空。

这与 QPI 或 UPI 链接的数量以及n 个CPU 之间的 Intel 可扩展性(因为您提到了 Xeon)有关,无论是 4S、S4S、S8S。但事实上,有 4 个插槽,意味着您应该能够在任何地方以合理的速度访问 RAM(S4S 比 4S 快),但在这个级别最坏的情况下,它将比访问磁盘或磁盘快几个数量级。一些其他类型的 PCIe 存储。

对于给定的进程,在四路系统中的 CPU 0、1、2 或 3 上的某个特定内核上运行,那么最快的 RAM 访问就是挂在给定 CPU 内存控制器上的 RAM 芯片池。如果它必须跳过 QPI/UPI 链接到其他某个 cpu,然后才能访问该 RAM,那么速度会更,而且不是最佳的。但您首先必须权衡这一切与没有足够的共享 RAM 的关系。

是的,有一种方法可以强制解决这个问题,那就是

cpuset - 将进程限制为处理器和内存节点子集

cpuset 文件系统是内核 cpuset 机制的伪文件系统接口,用于控制进程的处理器放置和内存放置。它通常安装在/dev/cpuset。