2012年12月23日星期日

NUMA基础知识


这一周开始涉猎一些服务器性能调优的工作,主要是NUMA机器上的scalability的问题,比较有意思,所以在此记录一下。
NUMA是Non-Uniform Memory Access 的简称,是一种多核处理器机器的架构。和SMP不同,SMP是一种Uniform Memory Access,即所有CPU访问同一内存地址的时间一样,而NUMA上不同CPU访问同一地址所需要的时间是不同的。SMP是没有办法添加太多CPU了,因为内存的带宽有限,过多CPU造成的竞争没法解决,而NUMA突破了SMP机器上架构上的限制,可以有几十个甚至上百个CPU。
具有 4 个处理器的 NUMA 节点
NUMA把若干CPU归为一个node,每个node都有专属自己的local memory和系统总线。处于同一node的CPU访问自属于这个node的local memory速度是一致的,而且是最快的。一旦到了需要访问其它node的memory时,这种内存访问称为remote memory access,其速度就会比访问local memory慢很多,因为它需要通过系统总线和memory hub。
可以使用这条命令来看local memory access和remote memory access的区别。
numactl –cpunodebind=0 numademo 256m memset
结果如下
[xxx@xxx ~]$ numactl –cpunodebind=0 numademo 256m memset
2 nodes available
memory with no policy memset Avg 7571.95 MB/s Max 8428.64 MB/s Min 5787.87 MB/s
local memory memset Avg 7987.18 MB/s Max 8430.76 MB/s Min 6215.51 MB/s
memory interleaved on all nodes memset Avg 5723.35 MB/s Max 6364.35 MB/s Min 4109.17 MB/s
memory on node 0 memset Avg 7766.91 MB/s Max 8434.21 MB/s Min 6094.71 MB/s
memory on node 1 memset Avg 4592.07 MB/s Max 5134.67 MB/s Min 3922.37 MB/s
memory interleaved on 0 1 memset Avg 6035.05 MB/s Max 6366.01 MB/s Min 5416.59 MB/s
setting preferred node to 0
memory without policy memset Avg 7813.53 MB/s Max 8430.76 MB/s Min 6219.83 MB/s
setting preferred node to 1
memory without policy memset Avg 4705.41 MB/s Max 5103.24 MB/s Min 3813.17 MB/s
manual interleaving to all nodes memset Avg 5557.70 MB/s Max 6357.11 MB/s Min 4561.12 MB/s
manual interleaving on node 0/1 memset Avg 5895.08 MB/s Max 6417.76 MB/s Min 4903.92 MB/s
current interleave node 0
running on node 0, preferred node 0
local memory memset Avg 7691.27 MB/s Max 8460.79 MB/s Min 6435.14 MB/s
memory interleaved on all nodes memset Avg 5836.12 MB/s Max 6368.58 MB/s Min 4561.97 MB/s
memory interleaved on node 0/1 memset Avg 5646.38 MB/s Max 6361.78 MB/s Min 4572.77 MB/s
alloc on node 1 memset Avg 4634.88 MB/s Max 5101.78 MB/s Min 4013.63 MB/s
local allocation memset Avg 7135.54 MB/s Max 8310.44 MB/s Min 5955.31 MB/s
setting wrong preferred node memset Avg 4719.06 MB/s Max 5100.43 MB/s Min 3942.65 MB/s
setting correct preferred node memset Avg 7773.80 MB/s Max 8435.27 MB/s Min 6498.70 MB/s
running on node 1, preferred node 0
local memory memset Avg 8502.54 MB/s Max 8581.70 MB/s Min 8416.49 MB/s
memory interleaved on all nodes memset Avg 6376.26 MB/s Max 6450.60 MB/s Min 6339.40 MB/s
memory interleaved on node 0/1 memset Avg 6497.49 MB/s Max 6507.53 MB/s Min 6474.41 MB/s
alloc on node 0 memset Avg 5204.73 MB/s Max 5219.64 MB/s Min 5181.85 MB/s
local allocation memset Avg 8624.27 MB/s Max 8641.09 MB/s Min 8579.78 MB/s
setting wrong preferred node memset Avg 5200.46 MB/s Max 5211.43 MB/s Min 5176.95 MB/s
setting correct preferred node memset Avg 8620.58 MB/s Max 8641.37 MB/s Min 8579.50 MB/s
基本上,scalability的问题都是由内存访问速度不一致导致的,MIT的人在这方面做了一个很经典的研究(链接),我现在也基本遵循了他们的方法来做。他们发现的两个问题都非常典型,首先是spin lock,这种test&set全局变量的操作,导致很多CPU都在做cache cohernet,然后做cache一致性时需要的全局变量的值需要remote memory access,导致了性能的剧烈下降。第二个例子是reference counting,导致性能下降的原因也和spin lock相同。
一般调优NUMA上的性能就使用numactl命令,把进程绑定到某一节点上,这样可以解决大部分的问题。可以先通过numactl –show或者numactl –hardware来查看硬件信息,而numastat可以看到开机运行到现在的内存分配的locality。
numactl –localalloc –cpunodebind=nodeid progname
现在还只有一些初步了解,希望可以快速学习相关知识,追上大家的脚步。
PS:关于DL980准确的硬件描述应该如下,拷贝自HP的文档:
The above table shows the logical processor assignments for the first two processors from a 64-core DL980 (8 processors with 8 cores per processor) with Hyper-threading enabled. The Physical ID is the physical processor socket. Core ID is the processing core on a particular physical processor. Thus, logical processor numbers 0 and 64 are the two threads on the first core on the first physical processor.

没有评论: