對Intel Sandybridge 系列CPU 中的流水線程序進行去優化
問題:
任務是在給定程式中引入低效率,以減慢其執行速度。該程式是使用高斯隨機數的蒙特卡羅模擬,重點是利用 Intel Sandybridge 系列 CPU 的管道結構。
解決方案:
導致管道效率低下危險:
-
將原子操作與儲存載入柵欄一起使用:對共享變數的重複原子操作會建立記憶體依賴性,導致管線停頓。此外,儲存載入柵欄會強制記憶體操作的串列執行。
-
建立錯誤共享:確保多個執行緒存取不同快取行中的相鄰記憶體位置,導致快取群組衝突和失效。
-
使用不規則的記憶體存取模式:避免順序記憶體存取以防止高效率的預取和快取利用。例如,以不連續的順序存取元素或使用鍊錶代替陣列。
弱化循環級並行性:
-
序列化循環迭代:使用鎖定或原子增量等同步機制來確保只有一次執行緒一次執行每個循環迭代。
-
引入不可預測的分支:包含分支預測器難以預測的分支,當採取錯誤的路徑時會導致錯誤預測和管道刷新。
-
使用低效運算:用較慢的替代方案替換高效的算術運算,例如除法而不是乘法,或平方用根代替乘法,用常數乘法代替對數和指數函數。
利用微架構功能:
-
導致不必要的暫存器溢位和填充:使用許多局部變數和大型資料結構,強制溢位和填充操作
-
使用低效指令:利用會導致嚴重停頓或降低指令級並行性的指令,例如未對齊的內存存取或32 位元模式下的16 位元操作。
-
爭奪快取資源:透過存取多個陣列或資料結構造成過多的快取未命中同時,使用非連續記憶體存取模式,或使用CLFLUSH 等指令明確使快取行無效。
編譯器最佳化避免:
-
使用內聯彙編:透過使用內聯彙編手動控制指令產生來繞過編譯器最佳化,並避免快取友善的程式碼轉換。
-
使用未定義的行為:執行可能導致意外行為或產生低效程式碼的操作,例如非指標類型或未初始化記憶體上的指標算術
-
強制不必要的重新編譯:以需要重新編譯的方式更改程式碼,例如新增註解或修改巨集,以使快取的程式碼路徑無效並降低編譯器最佳化的有效性。
結論:
作者將這些低效率的問題納入程序中,可以顯著降低其執行速度,並凸顯優化現代管道架構代碼的重要性。然而,值得注意的是,這些技術並不是為了在實際應用中實際使用,而只是為了說明不良最佳化對效能的潛在影響。
以上是我們如何有意地對程式進行去最佳化以暴露 Intel Sandybridge 管道瓶頸?的詳細內容。更多資訊請關注PHP中文網其他相關文章!