在你進程裡不是所有內存條訪問起來都一樣快

現在的服務器物理機CPU都是幾十核,而且物理個數可能還不止一個。內存也是由許多的內存條組成,幾十GB甚至是上百G。那麼我這裡幾個簡單的問題,

這麼多的CPU和內存它們之間是怎麼互相連接的?你寫的應用程序進程如果訪問不同的內存條延時一樣嗎?答案肯定是不一樣的,那麼我們今天在Linux上實際查看一下。

簡單的CPU與內存的連接:FSB時代

FSB的全稱是Front Side Bus,因此也叫前端總線。CPU通過FSB總線連接到北橋芯片,然後再連接到內存。內存控制器是集成在北橋裡的,Cpu和內存之間的通信全部都要通過這一條FSB總線來進行。

在你進程裡不是所有內存條訪問起來都一樣快

圖1 FSB總線下CPU與內存的連接方式

在這個年代裡,當時提高計算機系統整體性能的方式就是不斷地提高CPU、FSB總線、內存條的數據傳輸頻率。

多CPU多內存條複雜互聯:NUMA時代

當CPU的主頻提升到了3GHz每秒以後,硬件製造商們發現單個CPU的已經到了物理極限了。所以就改變了性能改進的方法,改成為向多核、甚至是多CPU的方向來發展。在這種情況下,如果仍然採用FSB總線,會導致所有的CPU和內存通信都經過總線,這樣總線就成為了瓶頸,無法充分發揮多核的優勢與性能。所以CPU製造商們把內存控制器從北橋搬到了CPU內部,這樣CPU便可以直接和自己的內存進行通信了。那麼,如果CPU想要訪問不和自己直連的內存條怎麼辦呢?所以就誕生了新的總線類型,它就叫QPI總線。

在你進程裡不是所有內存條訪問起來都一樣快

圖2 QPI總線下的CPU與內存連接方式

圖中CPU1如果想要訪問內存3的話,就需要經過QPS總線才可以。

Linux下NUMA架構查看

我們先通過dmidecode命令查看一下內存插槽,單條大小等信息。大家可以試著在linux上執行以下該命令。輸出結果很長,大家可以有空仔細研究。我這裡不全部介紹,這裡只挑選一些和內存相關的:

# dmidecode|grep -P -A5 "Memory\\s+Device"|grep Size 
Size: 8192 MB
Size: 8192 MB
Size: No Module Installed
Size: 8192 MB
Size: No Module Installed
Size: 8192 MB
Size: 8192 MB
Size: 8192 MB
Size: No Module Installed
Size: 8192 MB
Size: No Module Installed
Size: 8192 MB

可以看出,我當前使用的機器上共有16個內存插槽,共插了8條8G的內存。所以總共是64GB。如我們前面所述,在NUMA架構裡,每一個物理CPU都有不同的內存組,通過numactl命令可以查看這個分組情況。

# numactl --hardware
available: 2 nodes (0-1)
node 0 cpus: 0 1 2 3 4 5 12 13 14 15 16 17
node 0 size: 32756 MB

node 0 free: 19642 MB
node 1 cpus: 6 7 8 9 10 11 18 19 20 21 22 23
node 1 size: 32768 MB
node 1 free: 18652 MB
node distances:
node 0 1
0: 10 21
1: 21 10

通過上述命令可以看到,每一組CPU核分配了32GB(4條)的內存。 node distance是一個二維矩陣,描述node訪問所有內存條的延時情況。 node 0裡的CPU訪問node 0裡的內存相對距離是10,因為這時訪問的內存都是和該CPU直連的。而node 0如果想訪問node 1節點下的內存的話,就需要走QPI總線了,這時該相對距離就變成了21。

所以、今天我們的結論是,在NUMA架構下,CPU訪問自己同一個node裡的內存要比其它內存要快!


分享到:


相關文章: