2014-05-08 31 views
1

我正在研究一個令人難以置信的性能關鍵項目,其中每個時鐘週期都計入我最重要的內部循環中。我在考慮重構代碼以隱藏指令延遲,但是我想知道現代CPU的無序執行硬件在多大程度上已經爲我做了這些。考慮下面的(簡單假設)例如:無序硬件:它有多「聰明」?

// Increment three counters. These instructions should all execute in 
// parallel with latency of one cycle. Assume the previous register values 
// have been computed a long time ago and are ready to use by the time 
// these are decoded. 
add RAX, 1; 
add RBX, 2; 
add RCX, 3; 

// Multiply takes at least three cycles. Again, assume both inputs are 
// ready by the time we get here. 
imul RDX, RDI; 

// Use the result of the imul immediately in a long dependency chain. 
mov RDX, [RDX]; 
cmp RDX, 1; 
jae LBlahBlahBlah; 

我的問題是下列哪項適用:

  • 現代主流亂序硬件將重新排列三個add的指令前,imul即使add指令以編程方式出現在imul之前,並且在解碼時可以獲得所有輸入相關性。 imuladd指令的延遲時間更長,並立即用於依賴鏈中,因此這是最佳選擇。

  • 亂序執行只發生在編程式先前的指令不能執行由於缺少輸入相關性而被解碼時執行。硬件不能指望「前瞻」來優化這種動態。

+2

我不能回答你的問題,但它變化的基礎涉及的實際CPU和特別說明,我猜。不過,編譯器肯定會爲你做這種優化。 –

+1

您會發現現代x86硬件*非常*能夠重新排序長距離和跨循環迭代的事物,前提是沒有分支預測失誤。 – Mysticial

回答

1

你的第二個解釋是正確的,背後的想法亂序執行是確保長期依賴鏈或其他長時間運行的指令(如內存訪問)不會阻止獨立的操作(如兩者之間的附加寄存器與長時間運行的指令無關),並允許它們並行執行。但是,指令是按順序提取和解碼的。處理器不能預測程序,決定一個指令是一個獨立指令,並在檢索其他指令之前運行它。那是編譯器想要優化的地方。

在您的例子中,取指令和順序解碼,第一add RAX, 1,然後add RBX, 2,然後add RCX, 3然後imul RDX, RDI(儘管你可以讀取和處理器是否超標量解碼多重的,但畢竟是一個獨立的概念) 。每個將依次發送到適當的保留站,但是,如果只有一個單元來執行添加,那麼亂序方面會出現,一些添加可能與imul同時執行;這是非常依賴的架構。

如果時間要求的細節非常嚴格,那麼您將需要對現代高速架構非常小心,因爲它們具有大量複雜結構以提高性能。但是,根據代碼運行情況,這些機制可能會導致嚴重的延遲。分支預測和緩存只是在發生未命中或錯誤預測時發生延遲的兩個原因(或正確使用時提高了吞吐量)。你最好的選擇是獲得一個精確週期的處理器模擬器,以確保你的代碼能夠滿足要求(或者你可以使用實際的硬件)。

另外請注意,如果您使用的是現代建築,我想你可能有一個操作系統運行,這是一個軟件,它會摧毀你正在試圖獲得超高性能的水平。