如今開始補日誌,逐步的掃清之前寫了一半的和「欠帳未還的」。半年以前開的頭,今天先把NUMA說完。node
PC硬件結構近5年的最大變化是多核CPU在PC上的普及,多核最經常使用的SMP微架構:redis
- 多個CPU之間是平等的,無主從關係(對比IBM Cell);
- 多個CPU平等的訪問系統內存,也就是說內存是統一結構、統一尋址的(UMA,Uniform Memory Architecture);
- CPU到CPU的訪問必須經過系統總線。
結構如圖所示:api
SMP的問題主要在CPU和內存之間的通訊延遲較大、通訊帶寬受限於系統總線帶寬,同時總線帶寬會成爲整個系統的瓶頸。架構
由此應運而生了NUMA架構:併發
NUMA(Non-Uniform Memory Access)是起源於AMD Opteron的微架構,同時被Intel Nehalem採用(英特爾志強E5500以上的CPU和桌面的i三、i五、i7均基於此架構)。這也應該是繼AMD64後AMD對CPU架構的又一項重要改進。memcached
在這個架構中,每一個處理器有其能夠直接訪問其自身的「本地」內存池,使CPU和這塊兒內存之間擁有更小的延遲和更大的帶寬。並且整個內存仍然可作爲一個總體,能夠接受來自任何CPU的訪問。簡言之就是CPU訪問本身領地內的內存延遲最小獨佔帶寬,訪問其餘的內存區域稍慢而且共享帶寬。post
GNU/Linux如何管理NUMA:測試
- probe硬件,瞭解物理CPU數量,內存大小等;
- 根據物理CPU的數量(不是core)分配node,一個物理CPU對應一個node;
- 把屬於一個node的內存模塊和其node相聯繫;
- 測試各個CPU到各個內存區域的通訊延遲;
在一臺16GB內存,雙Xeon E5620 CPU Dell R710用numactl獲得如下信息:優化
# numactl --hardwarespa
available: 2 nodes (0-1)
node 0 size: 8080 MB
node 0 free: 5643 MB
node 1 size: 8051 MB
node 1 free: 2294 MB
node distances:
node 0 1
0: 10 20
1: 20 10
- 第一列node0和node1就是對應物理CPU0和CPU1;
- size就是指在此節點NUMA分配的內存總數;
- free是指此節點NUMA的內存空閒數量;
- node distances就是指node到各個內存節點之間的距離,默認狀況10是指本地內存,21是指跨區域訪問。
由於就近內存訪問的快速性,因此默認狀況下一個CPU只訪問其所屬區域的內存空間。此時形成的問題是在大內存佔用的一些應用時會有CPU近線內存不夠的狀況,可使用以下方式把CPU對內存區域的訪問變爲round robin方式。此時須要經過如下方式修改:
# echo 0 > /proc/sys/vm/zone_reclaim_mode
# numactl --interleave=all
memcached、redis、monodb等應該作以上的優化修改。
另外,若是有時間,下一篇會總結一下本身對於此問題的思考:若是本身實現一個內存池,併發揮NUMA架構的最大效能,如何設計?
參考自:
Http://En.Wikipedia.Org/Wiki/Non-Uniform_Memory_Access
Ulrich Drepper, Memory part 4: NUMA support Http://Lwn.Net/Articles/254445/