記憶體階層與效能

走訪上述鏈結串列的處理,比讀取相同元素數量的陣列容易大幅變慢,其原因為下列何者?

struct node { int val; struct node *next; };
for (p = head; p != NULL; p = p->next)
    sum += p->val;
  1. A因為在讀取目前元素之前無法得知下一個元素的位址,未命中只能一個接一個依序發生
  2. B因為規定鏈結串列的元素完全不會進入快取
  3. C因為使用指標的處理一定會使CPU的分支預測失敗
查看答案與解析

正確答案:A. 因為在讀取目前元素之前無法得知下一個元素的位址,未命中只能一個接一個依序發生

在鏈結串列中,要讀取p->next之後才知道下一個元素的位址。若元素散布在記憶體上,每次存取都會發生未命中,而且因為不知道下一個位址,無法讓多個未命中重疊,主記憶體的等待時間會在每個元素上完整地累加。若是陣列,下一個位址可由計算得知,預取與未命中的重疊便能發揮作用。鏈結串列的元素同樣會進入快取,迴圈的分支也容易預測,並非一定失敗。

  • A. 正確。無法得知下一個位址,未命中的等待時間會逐一累加。
  • B. 鏈結串列的元素同樣會進入快取。
  • C. 迴圈的分支有規律,預測並非一定失敗。
練習這個領域 前往領域頁面

記憶體階層與效能的其他題目

  1. 一次未命中讀取64位元組的快取行,主記憶體的等待時間為100 ns時,若同時能處理的未命中只有1個,讀取頻寬只有約0.64 GB/s。若能同時處理10個未命中,頻寬約為多少?(假設沒有其他限制)
  2. 寫出一次寫入後暫時不會再讀回的大量資料時,使用不經過快取的儲存(非暫存儲存,non-temporal store)的主要優點為下列何者?
  3. 快取的命中率為95%時,未命中率為多少?
  4. 從主記憶體載入未命中的快取行時,先送出CPU所需的字組(word),其餘的稍後再送的手法為下列何者?
  5. 將上述兩個迴圈合併為一個(迴圈融合,loop fusion)後,當N很大時容易變快,其原因為下列何者?

這個領域的比較