2013-11-24 128 views
1

我試圖複製的第一塊代碼本文C循環的緩存優化:爲什麼這不起作用?

http://www.drdobbs.com/parallel/cache-friendly-code-solving-manycores-ne/240012736

即上:

static volatile int array[Size]; 
static void test_function(void) 
{ 
    for (int i = 0; i < Iterations; i++) 
     for (int x = 0; x < Size; x++) 
      array[x]++; 
} 

我在OS X運行與Ivy Bridge處理器,所以具有一級緩存64KiB。但是,無論我在數組大小周圍進行多少更改,都需要相同的時間。這裏是我的代碼:

#define ARRAY_SIZE 16 * 1024 
#define NUM_ITERATIONS 200000 

volatile int array[ARRAY_SIZE]; 

int main(int argc, const char * argv[]) 
{ 
    for (int i = 0; i < NUM_ITERATIONS; i++) 
     for (int x = 0; x < ARRAY_SIZE; x++) 
      array[x]++; 
    return 0; 
} 

現在,根據文章所建議的邏輯,array應該是64KiB和利用我所有的L1緩存。然而,我已經嘗試過使用ARRAY_SIZE(最多160 * 1024)的許多差異組合,因此相應地設置了NUM_ITERATIONS,但每個組合都需要相同的時間。

我使用gcc -o cachetest cachetest.c進行編譯,沒有其他選項。是否存在某種我不知道的優化,儘管使用了volatile?還是有那麼多的並行進程和上下文切換,我甚至無法分辨?這裏發生了什麼?我很困惑。

謝謝!

+0

什麼原因它是在最佳時間開始運行檢查由編譯器生成的代碼的程序集文件!? *錫箔帽子* – StoryTeller

+0

快速看一下彙編程序會告訴你編譯器是否已經將這些代碼優化爲無。 –

+0

處理器可能預加載數據?我們正在順序訪問它。儘管如此,請不要對此表態。 – Guido

回答

1

有兩件事情:

  • 編譯器可能會做一些默認的優化你的代碼
  • 你的代碼中任何其他代碼/功能,不使用array,它只是增加內部循環數組值,所以編譯器可以通過改變你的程序不做任何事情(只返回0)來更好地優化它,這仍然是正確的。

我建議:

  • 添加更多的代碼在循環中,因此編譯器不會消除你的代碼,例如:printf的數組值或數組值添加到一個總和變量,然後打印循環結束時的總和變量。
  • 使用-O0選項編譯時關閉所有編譯器優化。
  • 使用-S選項