2012-04-08 55 views
-1

考慮下面的代碼:緩存未命中?我怎麼能看到?

for (int i=0; i<n; i++) 
{ 
    counter += myArray[i]; 
} 

,循環展開版本:

for (int i=0; i<n; i+=4) 
{ 
    counter1 += myArray[i+0]; 
    counter2 += myArray[i+1]; 
    counter3 += myArray[i+2]; 
    counter4 += myArray[i+3]; 
} 

total = counter1+ counter2 + counter3+ counter4; 
  1. 爲什麼我們在第一個版本高速緩存未命中?
  2. 第二個版本的確比第一個版本有更好的表現嗎?爲什麼?

問候

+3

是什麼讓你認爲存在的第一個版本高速緩存未命中? – templatetypedef 2012-04-08 19:40:08

+0

我不知道還會有差別很大...... – 2012-04-08 19:40:10

+0

氣味像功課太多... – m0skit0 2012-04-08 19:40:13

回答

4

爲什麼我們在第一個版本的高速緩存未命中?

正如奧利在評論中指出的那樣。這個問題沒有根據。如果數據已經在緩存中,那麼將不存在緩存未命中。

除此之外,您的兩個示例在內存訪問方面沒有區別。所以這不會成爲它們之間性能差異的一個因素。

第二個版本是否確實比第一個版本有更好的性能?爲什麼?

通常,要做的事情是實際測量。但在這個特定的例子中,我會說它可能會更快。不是因爲更好的緩存訪問,而是因爲循環展開。

您正在進行的優化稱爲「節點分割」,您將分割counter變量以打破依賴關係鏈。

但是,在這種情況下,您正在做一個簡單的約簡操作。許多現代編譯器都能夠識別這種模式,併爲您執行此節點分割。

那它快嗎?最有可能的。但是你應該檢查一下,看看編譯器是否爲你做。


爲了記錄:我只是測試這在Visual Studio 2010中
而且我很驚訝,這是無法做到這一點的優化。

; 129 : 
; 130 :  int counter = 0; 
; 131 : 
; 132 :  for (int i=0; i<n; i++) 
    mov ecx, DWORD PTR n$[rsp] 
    xor edx, edx 
    test ecx, ecx 
    jle SHORT [email protected] 
[email protected]: 

; 133 :  { 
; 134 :   counter += myArray[i]; 

    add edx, DWORD PTR [rax] 
    add rax, 4 
    dec rcx 
    jne SHORT [email protected] 
[email protected]: 

; 135 :  } 

Visual Studio 2010中似乎沒有能夠爲這個(簡單)例如進行「節點分離」的...

相關問題