NUMA——Non Uniform Memory Access,中文为非统一内存访问,在NUMA出现之前,内存的控制器是包含在北桥芯片中的,所有内存由北桥统一管理,因此可以保证访问内存的一致性。随着CPU架构的不断迭代和演进,核数越来越多,对数据吞吐、性能的需求增加,内存的控制器(IMC)也被集成到了CPU中,从此北桥芯片也就消失在主板上。因此产生了NUMA,即:每个Node 节点下都与自己专属的内存(local),如果访问其他Node节点下的内存,就为远端内存(remote)
科普:当前我们Purly平台(skylake、Cascade lake、Cascade lake R)单个CPU上IMC的数量为2个,每个IMC控制3个channel,每个channel又分为2个DIMM。这里的DIMM就是实际对应的物理插槽。蓝色部分代表CPU(里面包含多个物理核心+cache+IMC等物理结构)、双向剪头代表channel共6个,绿色代表内存条,单个CPU最大支持12条(每个channel拓展2个DIMM,分为主和副,每个DIMM可插一个内存条),占用的channel数量越多,内存吞吐越大,直至占用所有的主DIMM,则能发挥出CPU全部的性能。
图中两个物理CPU之间使用Intel UPI/QPI进行数据交换等通信,UPI/QPI是CPU之间唯一的高速通路,注:跨UPI/QPI会造成一定的访问时长增加(ns级别)相关原文链接参考: QPI/UPI
那么自从有了NUMA后,Linux系统内默认的内存分配方案就是“优先请求当前运行程序CPU的本地内存,如果申请本地内存时出现内存不足则会通过跨UPI/QPI的方式访问,另外一颗CPU下挂载的内存,那么这个时候会增加访问延迟;当我们关闭NUMA的时候那么系统会允许我们在两个物理CPU下挂载的所有内存进行交叉访问,当然这个结果一定会比我们访问本地内存时间要长,但还是要低于跨UPI/QPI时访问时间”我们可以通过一个简单的测试工具来实验一下。
测试环境:Centos 7.3、内核3.10.514
测试配置:Intel(R) Xeon(R) Silver 4214 CPU @ 2.20GHz * 2 + 8*16G-2666MHz Memory
测试工具:MLC-3.9(Memory Latency Check)
测试命令:./mlc --latency_matrix
测试结果:
(1) NUMA Enabled:
NUMA Node(ns) | 0 | 1 |
---|---|---|
0 | 79.8 | 136.2 |
1 | 136.4 | 79.7 |
(2)NUMA Disabled:
NUMA Node(ns) | 0 |
---|---|
0 | 120.8 |
同时最近在做数据库测试的时候发现:相同的workload,在256G内存和在128G内存上数据库数据导出时长不同,内存使用量约为30G,且256G内存导出时间要远大于128G导出时间”,通过监控查看有数据导出时CPU、Memory、NVMe占用率,结果发现128G内存占用率已经接近70%,而256G内存占用率还不到50%,在这台128G内存机器上查询内存命中率。
numastat 可以看到如下两个数据,第一个是numa_hit:预期的内存在这个节点上成功分配;第二个是指:在这个节点上分配内存,但进程使用了不同的节点。通过上图我们看到了在这台128G内存机器上出现了大量的numa_miss,顾名思义就是产生大量的跨UPI/QPI调用远端内存,因此导致了相同的压力(内存需求30G)在128G和256G内存机器上的差异。
(免费订阅,永久学习)学习地址: Dpdk/网络协议栈/vpp/OvS/DDos/NFV/虚拟化/高性能专家-学习视频教程-腾讯课堂
更多DPDK相关学习资料有需要的可以自行报名学习,免费订阅,永久学习,或点击这里加qun免费
领取,关注我持续更新哦! !
优化:关闭NUMA(优点:减低跨NUMA访问时长,缺点:没有local内存概念,所以本地内存不存在低访问时长的优势)
在不改变内存容量的前提下如何优化呢?基于此做了一个实验,用数据库中的Demo多次进行测试:
这里有个有意思的问题:就是当NUMA:enabled时出现numa_miss时其实整体的运行时间还是会低于NUMA:Disabled;就是因为大量的内存还是优先访问本地,出现少量的miss还不足以导致整体运行时间增加,但如果数据量占用内存过大,或者原本本地内存被各种服务占用,本地内存不够,但remote内存过剩时,可以通过绑定Node节点的方式提高程序运行效率(numactl -N 【socket ID】 -m 【memory ID】)。
可用如下命令查看每个Node内存占用率:
[root@localhost ~]# numactl -H
available: 2 nodes (0-1)
node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 24 25 26 27 28 29 30 31 32 33 34 35
node 0 size: 130669 MB
node 0 free: 112885 MB
node 1 cpus: 12 13 14 15 16 17 18 19 20 21 22 23 36 37 38 39 40 41 42 43 44 45 46 47
node 1 size: 131072 MB
node 1 free: 102788 MB
node distances:
node 0 1
0: 10 21
1: 21 10