icc(Intel C++ Compiler)是一個非常厲害的編譯器,對優化計算密集型的程式遠超其他任何編譯器,如gcc、llvm、Visual C++。
icc提供了過程間優化(Interprocedural Optimization)技術,可以幫助編譯器在不同的目标檔案之間進行全局優化。傳統的編譯器的編譯過程是編譯每個源檔案到獨立的目标檔案,然後再通過連結器将目标檔案連結成可執行檔案。傳統的編譯器的編譯優化主要集中在每個源檔案内部,連結過程比較簡單,是以每個檔案都是獨立的,而icc提供的過程間優化打破了這一限制。
過程間優化可以對整個程式進行全局優化,而不是僅僅在單個檔案、單個函數或者單個代碼塊内部優化。過程間優化可以減少過程之間重複計算、記憶體的低效通路以及簡化疊代過程,通常會采用内聯函數的方式。過程間優化還可以重排代碼的順序以優化記憶體的配置設定方式和局部性。
通過指定編譯參數
-ipo
,icc可以開啟過程間優化,icc将在編譯時生成特殊格式的目标檔案(中間語言),并在連結時進行進一步的編譯和過程間優化,如圖所示:
使用icc啟動過程間優化的方式是在編譯參數中加上
-ipo
參數,還要設定環境變量
AR=xiar
,使用Intel的版本代替預設的
ar
。
性能分析引導優化(Profile Guided Optimization)通過分析程式運作時的實際行為,将結果回報給編譯器,使得編譯器可以重新安排代碼以減少指令緩存問題和分支預測誤判,進而獲得性能的提升。性能分析引導優化通過實際執行代碼統計出運作頻率最高的部分,編譯器通過這些資訊可以更加針對地優化代碼。性能分析引導優化分為三個階段:
- 第一步是生成分析程式。在這個階段,編譯器建立一個有采樣注入的可執行程式。在icc中使用的編譯指令是
,以及-prog-gen
。-prof-dir=[dir]
- 第二步是運作第一步生成的被注入采樣分析的程式,每次運作這個程式,都會生成
指定的目錄下生成一個動态資訊檔案(dynamic information file),将會被最終編譯時使用。-prof-dir
- 第三步是最終編譯的步驟。第二次編譯的時候,動态資訊檔案會合并成一個彙總檔案。通過彙總檔案,編譯器會嘗試将最常使用的執行路徑優化。
過程間優化和性能分析引導優化可能會互相影響,性能分析引導優化通常會幫助編譯器生成内聯函數,這會幫助過程間優化的效率。性能分析引導優化對分支預測效率的提升最有效果,許多分支執行的可能性無法在編譯時判斷,而通過性能分析引導優化,編譯器可以針對經常執行的分支(熱代碼)和不經常執行的分支(冷代碼)生成高效的彙編代碼。
使用性能分析引導優化的方法如下:
- 第一階段:編譯參數中加上:
。其中-prof-gen=srcpos -prof-dir=/tmp/profdata
是存儲性能分析檔案的目錄。-prof-dir
- 第二階段:運作編譯好的程式,然後運作
生成彙總檔案。profmerge -prof_dir /tmp/profdata
- 第三階段:重新編譯程式,使用參數:
。-prof-use=nomerge -prof-func-groups -prof-dir=/tmp/profdata
這樣最終生成的代碼就是經過性能分析優化過後的了。
以上方法在icc 14.0.2上試驗通過。