分享一篇文章:Gallery of Processor Cache Effects
作者 Igor Ostrovsky 在 Microsoft Microsoft's Parallel Computing Platform team 服務。這篇文章透過 C# 七個實作來講述 Processor cache 的影響。測試程式簡短但切中要害,適合作為瞭解 cache 的入門。下面引用一些有趣的例子,希望勾起大家的興趣:
- 下面的 code, loop1 和 loop2 的效能差異會是 1/16 嗎?
int[] arr = new int[64 * 1024 * 1024];
// Loop 1
for (int i = 0; i < arr.Length; i++) arr[i] *= 3;
// Loop 2
for (int i = 0; i < arr.Length; i += 16) arr[i] *= 3;
- 下面的 code ,loop1 和 loop2 跑得一樣快嗎?
int steps = 256 * 1024 * 1024;
int[] a = new int[2];
// Loop 1
for (int i=0; i<steps; i++) { a[0]++; a[0]++; }
// Loop 2
for (int i=0; i<steps; i++) { a[0]++; a[1]++; }
一些外國鄉民的討論:http://www.reddit.com/r/programming/comments/ax1nv/gallery_of_processor_cache_effects/
P.S. 在 a 哥面前班門弄斧了!!
9 則留言:
第一題還ok
第二題就被騙了, 還以為還在講Cache, 怎麼冒出了ILP, 而且例子不太好
我猜是想說這個吧?!
The modern processor has various parts that have a little bit of parallelism in them: it can access two memory locations in L1 at the same time, or perform two simple arithmetic operations.
例子不好是因為:
a[0]++; a[0]++;
沒有變成 a[0] +=2; 嗎?
作者想表達的是
a[0]++ 和 a[1]++ 可以平行執行
但是 a[0]++; a[0]++; 無法平行
例子不好是因為會讓人以為會被最佳化掉
而且要講ILP最好不要把Cache扯進來
再來就是這句話不太對
"it can access two memory locations in L1 at the same time"
查了一下資料Intel的L1 Cache: 1 load and 1 store per cycle, 但是不能兩個load同時
可以平行計算是否是基於有兩個ALU? 資料進了registers, 還跟cache有關嗎? 假如程式有最佳化的話.
平行指的是1 Cycle處理多個指令
必須滿足:
1. 硬體要有多個Resource
2. 指令間沒有相依性
下面只是示意, 真實的情況不是如此
Loop 1 無法平行, 需要6 cycles
Cycle 0: Load a[0]
Cycle 1: Add a[0]
Cycle 2: Store a[0]
Cycle 3: Load a[0]
Cycle 4: Store a[0]
Cycle 5: Store a[0]
Loop 2 可以平行, 只需3 cycles
Cycle 0: Load a[0] && Load a[1]
Cycle 1: Add a[0] && Add a[1]
Cycle 2: Store a[0] && Store a[1]
因此硬體必須要有2個ALU, Cache必須要dual-port
補充一下資料
p4 的 L1 Cache 只能同時1 load, 1 sotre
但是現在的架構是用Prefetcher去存取Cache:
The Intel Core microarchitecture includes in each processing core two prefetchers to the Level 1 data cache. In addition it includes two prefetchers associated with the Level 2 cache and shared between the cores.
看起來應該可以同時2 load, 我觀念還停留在10年前 Orz
Reference:
http://download.intel.com/technology/architecture/sma.pdf
Prefetcher的目的是用來兩個load嗎? 那是不是我寫 a[0]++; a[0]++; a[0]++; 就又不能平行了呢?
Prefetcher是用來加快記憶體存取
如何加快呢? 在某個Load指令還沒執行前,就把他要的資料抓到Cache裡面, 等到他要執行的時候, 資料就已經在Cache裡了, 就不需去等記憶體存取
接下來可能會有人問, 還沒執行那個指令怎麼會知道他要什麼資料? 說穿了其實就是用過去的資料來猜的, 例如某個指令上上一次抓了Address 100, 上一次抓101, 我們就可以猜說他接下來會抓102
p.s. 上述只是個例子, 實際的運作方式還是要看文件才知道
a[0]++; a[0]++; a[0]++; 有資料相依性無法平行
喔對,是我搞錯了。
張貼留言