2010年2月23日 星期二

[轉錄] Gallery of Processor Cache Effects

分享一篇文章:Gallery of Processor Cache Effects

作者 Igor Ostrovsky 在  Microsoft Microsoft's Parallel Computing Platform team 服務。這篇文章透過 C# 七個實作來講述 Processor cache 的影響。測試程式簡短但切中要害,適合作為瞭解 cache 的入門。下面引用一些有趣的例子,希望勾起大家的興趣:

  1. 下面的 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;



  2. 下面的 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 則留言:

Zhong-Ho Chen 提到...

第一題還ok
第二題就被騙了, 還以為還在講Cache, 怎麼冒出了ILP, 而且例子不太好

Keiko 提到...

我猜是想說這個吧?!
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; 嗎?

Zhong-Ho Chen 提到...

作者想表達的是
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同時

SCREAMLab 提到...

可以平行計算是否是基於有兩個ALU? 資料進了registers, 還跟cache有關嗎? 假如程式有最佳化的話.

Zhong-Ho Chen 提到...

平行指的是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

Zhong-Ho Chen 提到...

補充一下資料
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

87showmin 提到...

Prefetcher的目的是用來兩個load嗎? 那是不是我寫 a[0]++; a[0]++; a[0]++; 就又不能平行了呢?

Zhong-Ho Chen 提到...

Prefetcher是用來加快記憶體存取
如何加快呢? 在某個Load指令還沒執行前,就把他要的資料抓到Cache裡面, 等到他要執行的時候, 資料就已經在Cache裡了, 就不需去等記憶體存取

接下來可能會有人問, 還沒執行那個指令怎麼會知道他要什麼資料? 說穿了其實就是用過去的資料來猜的, 例如某個指令上上一次抓了Address 100, 上一次抓101, 我們就可以猜說他接下來會抓102
p.s. 上述只是個例子, 實際的運作方式還是要看文件才知道


a[0]++; a[0]++; a[0]++; 有資料相依性無法平行

87showmin 提到...

喔對,是我搞錯了。