2012-11-01 38 views
4

比方說,我有它的實現看起來是這樣的一個C++類:減少指令高速緩存未命中(在C++)

// ... 

MyClass::iterativeFunction() { 
    for (int i = 0; i < 1000000; i++) { 
      performAction(i); 
    } 
} 

MyClass::performAction(int index) { 
    // Block of code (non-inline-able) 
} 

// ... 

在C++水平,我必須在這些方法的空間局部性的任何控制,還是我只希望編譯器能夠注意到相關的方法並相應地優化其組裝?理想情況下,我希望它們彼此相鄰,這樣它們將一起加載到指令緩存中,但我不知道如何讓編譯器知道我真的很希望發生這種情況。

+2

「我希望它們彼此相鄰,這樣它們將一起加載到指令緩存中。」這不是現代CPU的指令緩存的工作原理。它不會僅僅因爲它恰好接近其他代碼而提取代碼。它會提取代碼,因爲該代碼被調用。 –

+0

將inline/_forceinline/__ pleasepleaseinline標記爲「performAction」? – James

+2

隨着整個程序的優化,編譯器很可能會發現'MyClass :: performAction'的唯一調用者是'iterativeFunction',並且仍然內聯它。只有一個調用者的函數的內聯閾值要低得多。 – MSalters

回答

5

在這兩種情況下,代碼在進入緩存之前都不能運行。在任何一種情況下,代碼流所經過的CPU都是顯而易見的,因爲流是無條件的。所以它不會有任何區別。現代代碼緩存不會在地址空間中提前獲取,它會在指令流程中提前獲取,在無條件分支之後進行並根據需要預測條件分支。

所以沒有理由關心這一點。它不會有任何區別。

+0

好的,謝謝。我沒有意識到取指操作遵循指令流程。這讓我的生活變得更加輕鬆。 – Ephemera

0

不,據我所知,你無法指定你的方法的位置。 如果C++允許使用嵌套過程來確保被調用過程是本地的。

1

如果您需要這樣的控制和優化級別,那麼C++對您而言是錯誤的語言。

但您的問題的實際答案是「否」。

2

從技術上講,沒有。但是,在現代ish處理器中,您不需要擔心指令緩存的數量與數據緩存的差不多,除非您有一個非常大的可執行文件或任何地方非常可怕的分支。

原因是緩存行只有大約64個字節長,這意味着如果你的方法大於64字節(他們是),它們將需要被加載到多個緩存項中,即使它們是直接的在物理內存中彼此相鄰。

+0

對於任何現代CPU的編碼,認爲OP是沒有意義的。 –

相關問題