1、进程绑定NUMA节点或cpu核心的意义
NUMA 架构将内存和cpu分散在不同的 NUMA 节点上,每个节点都有自己的本地内存和cpu处理器,将进程绑定到特定的 NUMA 节点或cpu上,可以让进程直接访问本地内存和CPU,减少访问远程节点开销,提高访问速度,从而提高程序性能。
注:不可多进程绑定同一个节点或cpu,这样反而会使该节点产生资源竞争,降低性能。
2、查看NUMA架构的信息
[root@test ~]# yum -y install numactl
[root@test ~]# numactl -H
available: 2 nodes (0-1) #有两个NUMA节点,编号0,1
node 0 cpus: 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 #节点0包含的cpu核心编号
node 0 size: 65442 MB #节点0共有65442MB的内存容量
node 0 free: 5901 MB #节点0当前有5091MB的内存空闲
node 1 cpus: 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31
node 1 size: 65536 MB
node 1 free: 5133 MB
node distances: #不同node之间发访问距离(跳数),如[0,0] 表示node 0的本地内存访问距离为10。跳数(hops):表示从一个节点到达另一个节点所需的内存访问步骤数,并不是一个精确的时间或距离单位,而是一种相对指标。
node 0 1
0: 10 21
1: 21 10
[root@test ~]#
[root@test ~]# lscpu
...
#系统的NUMA节点和 CPU 核心编号的映射
NUMA node0 CPU(s): 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30
NUMA node1 CPU(s): 1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31
...
[root@test ~]#
[root@test ~]# yum -y install hwloc
[root@test ~]# lstopo-no-graphics
Machine (128GB total) #总共有128GB内存
NUMANode L#0 (P#0 64GB) #节点 L#0 有64GB内存
Package L#0 + L3 L#0 (20MB)
L2 L#0 (256KB) + L1d L#0 (32KB) + L1i L#0 (32KB) + Core L#0
PU L#0 (P#0)
PU L#1 (P#16)
L2 L#1 (256KB) + L1d L#1 (32KB) + L1i L#1 (32KB) + Core L#1
PU L#2 (P#2)
PU L#3 (P#18)
L2 L#2 (256KB) + L1d L#2 (32KB) + L1i L#2 (32KB) + Core L#2
PU L#4 (P#4)
PU L#5 (P#20)
L2 L#3 (256KB) + L1d L#3 (32KB) + L1i L#3 (32KB) + Core L#3
PU L#6 (P#6)
PU L#7 (P#22)
L2 L#4 (256KB) + L1d L#4 (32KB) + L1i L#4 (32KB) + Core L#4
PU L#8 (P#8)
PU L#9 (P#24)
L2 L#5 (256KB) + L1d L#5 (32KB) + L1i L#5 (32KB) + Core L#5
PU L#10 (P#10)
PU L#11 (P#26)
L2 L#6 (256KB) + L1d L#6 (32KB) + L1i L#6 (32KB) + Core L#6
PU L#12 (P#12)
PU L#13 (P#28)
L2 L#7 (256KB) + L1d L#7 (32KB) + L1i L#7 (32KB) + Core L#7
PU L#14 (P#14)
PU L#15 (P#30)
HostBridge L#0
PCIBridge
PCI 1000:005d
Block L#0 "sda"
PCIBridge
2 x { PCI 8086:154d }
PCIBridge
4 x { PCI 8086:1521 }
PCI 8086:8d62
PCIBridge
PCIBridge
PCIBridge
PCIBridge
PCI 102b:0534
GPU L#1 "card0"
GPU L#2 "controlD64"
PCI 8086:8d02
NUMANode L#1 (P#1 64GB) + Package L#1 + L3 L#1 (20MB)
L2 L#8 (256KB) + L1d L#8 (32KB) + L1i L#8 (32KB) + Core L#8
PU L#16 (P#1)
PU L#17 (P#17)
L2 L#9 (256KB) + L1d L#9 (32KB) + L1i L#9 (32KB) + Core L#9
PU L#18 (P#3)
PU L#19 (P#19)
L2 L#10 (256KB) + L1d L#10 (32KB) + L1i L#10 (32KB) + Core L#10
PU L#20 (P#5)
PU L#21 (P#21)
L2 L#11 (256KB) + L1d L#11 (32KB) + L1i L#11 (32KB) + Core L#11
PU L#22 (P#7)
PU L#23 (P#23)
L2 L#12 (256KB) + L1d L#12 (32KB) + L1i L#12 (32KB) + Core L#12
PU L#24 (P#9)
PU L#25 (P#25)
L2 L#13 (256KB) + L1d L#13 (32KB) + L1i L#13 (32KB) + Core L#13
PU L#26 (P#11)
PU L#27 (P#27)
L2 L#14 (256KB) + L1d L#14 (32KB) + L1i L#14 (32KB) + Core L#14
PU L#28 (P#13)
PU L#29 (P#29)
L2 L#15 (256KB) + L1d L#15 (32KB) + L1i L#15 (32KB) + Core L#15
PU L#30 (P#15)
PU L#31 (P#31)
[root@test ~]#
3、绑定
注:下述绑定方法都属于临时绑定,进程重启后失效;要永久生效,请在应用程序中设置绑定或配置文件里提前配置。
3.1 绑定NUMA节点
#运行前执行,将进程运行的cpu跟内存绑定到节点0上
numactl --cpunodebind=0 --membind=0 程序名
#接启动命令
numactl --cpunodebind=0 --membind=0 /usr/sbin/nginx
查看进程运行内存信息
[root@test ~]# numastat -p 223736
Per-node process memory usage (in MBs) for PID 223736 (nginx)
Node 0 Node 1 Total
--------------- --------------- ---------------
Huge 0.00 0.00 0.00 #使用的大页内存
Heap 0.94 0.00 0.94 #堆内存
Stack 0.02 0.00 0.02 #栈内存
Private 1.17 0.07 1.24 #其他使用内存
---------------- --------------- --------------- ---------------
Total 2.13 0.07 2.21
查看进程绑定cpu核心
[root@test ~]# taskset -c -p 223736
pid 223736's current affinity list: 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30
查看进程的 PID、所运行的 CPU 核心编号以及命令名称
[root@test ~]# ps -o pid,psr,comm -p 223736
PID PSR COMMAND
223736 22 nginx
3.2 绑定cpu核心
#绑定运行在6号cpu上
taskset -c 6 /usr/sbin/nginx
#绑定运行在0-6号cpu上
taskset -c 0,6 /usr/sbin/nginx
#绑定到NUMA架构1号节点上
numactl --cpubind=1 /usr/sbin/nginx
numactl --cpunodebind=1 /usr/sbin/nginx
查看进程运行在哪个cpu上
[root@test ~]# taskset -c -p 219877
pid 219877's current affinity list: 6
[root@test ~]# ps -o pid,psr,comm -p 219877
PID PSR COMMAND
219877 6 nginx