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 則留言:

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

    回覆刪除
  2. 我猜是想說這個吧?!
    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; 嗎?

    回覆刪除
  3. 作者想表達的是
    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同時

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

    回覆刪除
  5. 平行指的是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

    回覆刪除
  6. 補充一下資料
    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

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

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

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


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

    回覆刪除