揭穿內存廠家“謊言”,實測內存帶寬真實表現

帶寬是存儲系統一個的一個非常重要的衡量指標,內存帶寬指的是CPU從內存讀取或寫入數據到內存的速率。我們今天來思考一個問題,在你的應用程序裡內存的訪問帶寬能夠達到多少?

揭穿內存廠家“謊言”,實測內存帶寬真實表現


各代內存帶寬規格

理論上內存帶寬的計算公式是:Band Width = Speed * Data Width。在這個公式的基礎上,我們來看一下各代規格的內存帶寬表現。

揭穿內存廠家“謊言”,實測內存帶寬真實表現

圖1 各代內存帶寬規格

從上圖來看,DDR3代的內存 DDR3代1066MHz的帶寬都已經達到了8.5GB/s, DDR4代3200MHz更是達到了驚人的25.6G。 廠家在進行銷售的時候也都是用這個公式來算,言外之意就是告訴你:“我家的產品非常快,大家趕快來買啊!”

廠家這麼宣傳似乎也不算錯,但是有誘導性的謊言在其中。 廠家這個數據的基礎是內存嚴格以順序IO的方式工作,而且把傳輸的內存地址也當數據來看,進而計算出的結果。但我們在《內存隨機訪問也比順序慢,帶你深入理解內存IO過程》中明白了的是,內存在並一定是所有的Data Speed週期都在源源不斷往外吐數據。在CPU傳入了行地址後,內存打開一行需要tRCD+tRP個時鐘週期的延遲。輸入列地址後,又需要等待CL個時鐘週期。而內存作為易失性存儲元器件,又需要定時對所有的行進行充電,來保證數據不丟失。所以,在實踐中,我們並不是總是能夠達到廠家宣傳的理論帶寬值。

注意:理論帶寬值計算時採用的是內存的Speed,也就是其數據頻率。而內存的延遲呢,用的是時鐘週期。現代的內存在時鐘週期的上沿和下沿都可以傳輸數據,所以數據頻率比Speed又慢了一半。對於筆者Speed為1067MHz的內存條,其時鐘頻率是553MHz。

鄧爺爺說過,實踐是檢驗真理的唯一標準。我們今天就來進行一下實際的測試,看看內存的到底每秒能給我們吐出多少的數據。和前文《實際測試內存在順序IO和隨機IO時的訪問延時差異》的測試方法類似,我們今天對方法進行下小改動,用它來測試帶寬。

順序IO情況核心測試方法

測試代碼主體上和延遲測試差不多,定義一個指定大小的數組,然後以指定步長對其進行訪問。

void init_data(double *data, int n){ 
int i;
for (i = 0; i < n; i++) {
data[i] = i;
}
}

void seque_access(int elems, int stride) {
int i;
double result = 0.0;
volatile double sink;

for (i = 0; i < elems; i += stride) {
result += data[i];
}
sink = result;
}

考慮到內存對齊能提高性能,所以公平起見,我們每次都是按內存位寬去取的(一個double 8個字節,正好是一個內存位寬)。帶寬就是一秒內訪問過的字節總數,所以我們通過如下代碼進行計算。

result = total_accessed_bytes * 1000 / used_microseconds;

順序IO情況帶寬測試結果

筆者的服務器上的內存條是DDR3,1067MHz,延遲參數為7-7-7-24。我們進行了多場景的測試。

場景一: 固定數組大小2K,調節步長

揭穿內存廠家“謊言”,實測內存帶寬真實表現

圖2 固定數組大小2K,調節步長

數組為2k,足夠小到L1 cache全部都能裝的下。這時候其實基本實際內存IO發生的很少,大部分都是更高效的L1 cache的IO,在CPU內部就完成了。但最高值也才6G而已,也沒有達到廠家宣稱的8GB。

場景二: 固定步長為8,數組從32K到64M

揭穿內存廠家“謊言”,實測內存帶寬真實表現

圖3 固定步長為8,數組從32K到64M

數組越大,Cache越裝不下,數據訪問的IO會更多地往後穿透到L2、L3和內存。L1、L2、L3和內存IO的性能依次遞減,因此數組越大,平均帶寬就會越低。

場景三: 步長為32,數組從32K到64M

揭穿內存廠家“謊言”,實測內存帶寬真實表現

圖4 步長為32,數組從32K到64M

步長增加後,穿透到內存的次數進一步增加,帶寬進一步下降。這個時候,我們應用程序視角看到的數據帶寬已經下降到1GB以下了。

再測隨機IO情況

前面的測試情況,雖然步長也在變化,但都是有序遞增。這樣內存的連續兩次IO之間,雖然列地址會變,但是行地址極有可能不發生變化,因此效率還是算比較高。 我們這次是來徹底隨機進行訪問,再來看一下。

揭穿內存廠家“謊言”,實測內存帶寬真實表現

圖5 隨機訪問,數組從8K到64M

當數組比較小的時候,雖然亂序訪問,但是cache能兜住,因此內存IO實際上發生的很少。但當數組增加到64M的時候,再加上哪一級Cache都兜不住了。再加上訪問又足夠隨機,因此都穿透到了內存,而且行的行地址也極大可能發生變化。這時,內存帶寬竟然下降到了474M。

結論

所以內存的帶寬並沒有你想象的那麼快,在隨機IO工作模式的情況下,帶寬只有474M而已。 現在SSD固態硬盤順序IO也查不多能達到這個數量級了。

所以,我們以後不要魯莽地說內存比硬盤要快很多。快不快,關鍵取決於你怎麼用!


分享到:


相關文章: