如何分析和提高大型項目(C/C++)的編譯速度?
01-06
常見的有幾個:
1. Precompile header2. 多線程編譯3. 分散式編譯4. 改code,減少依賴性
另外還有一個VS2015特有的:/LTCG:incremental選項。以前為了執行性能,會開LTCG。但如此一來,就不能Incremantal。結果就是每次build和rebuild差不多速度。現在新加了/LTCG:incremental,就能兩者兼得。一定要打開precompiled header。不管你用了什麼其他的方法,precompiled header總是可以跟他們配合。Office還是用了VC++的一個功能,就是當你鏈接到lib文件的時候,會轉而去鏈接編譯出那個lib的obj文件,據說可以變快,反正我沒想明白為什麼。但這個功能倒是解決了一個千古難題,就是一個cpp文件的目的就只有運行全局變數的構造函數,然後cpp文件裡面定義的符號自然都不可能被別的cpp鏈接,直接鏈接該lib會導致這些代碼被刪掉。
1 ccache 簡單易用2 對於並行性高的可以distcc分散式編譯3 make -j4 並行編譯4 用doxygen之類的分析結構,剔除無關頭文件
1.減少代碼依賴.
2.聲明與實現分離,介面定義要相對穩定,include時候只include這個介面頭文件就好
3.適當的採用PIMPL模式,將實現放到CPP里
4.少用模板,因為模板是編譯期技術,大量採用模板也會增加編譯時間
1) 使用多線程。不管是Visual studio還是make之類都支持,但默認都是不打開的。
2) 用固態硬碟
以上方法都不要改代碼看看瓶頸在哪。大項目build臨時文件多,如果沒有的話,把讀和寫定向到不同物理磁碟,會有明顯的提升。
以前用Incredibuld, 可以分散式編譯,一般可以用12個CPU。單機rebuild solution要2-3小時,IncrediBuild大概30-40分鐘。
後來Visual Studio支持多核編譯了,基本上本機的編譯就足夠了,4核+超線程,跟IncrediBuild速度差不多。
後來還遇到有人用組磁碟陣列來提高Link速度的,我沒試過。現在用固態硬碟,這個技巧也沒啥用了。
還有一點,重構代碼,減少各個項目之間的依賴,高內聚,低耦合,多用一些OO設計原則,比如依賴倒置(DIP, 依賴介面不依賴於具體實現) 之類的。make -j20
方法很多,下面的方法都能顯著提升編譯性能:1、多任務並行編譯2、內存虛擬磁碟,純內存IO3、增量編譯4、分散式編譯5、使用高配製編譯機6、編譯選項優化7、換編譯器,用llvm普遍比gcc性能高
這個是伺服器部署(多CPU多任務分配,硬碟速度和並行)+最小修改集合編譯(makefile和ld)問題吧。
大項目那麼多人請求,伺服器不夠,線程再多浪費。
現在還可以在同一版本,別人編譯結果可以拷貝,為自己所用。使用分散式編譯工具,比如IncrediBuild
最近看到的:減少C++代碼編譯時間的方法以及大軟體的煩惱與編譯技術 ? 靈犀志趣
unit build具體自己Google
減少io開銷,預編譯,多任務編譯,項目足夠大就分散式編譯。就這幾個辦法了。另外,跪舔vc6的編譯速度!
使用工具將多個cpp通過#include 合併成一個cpp,工具的目的是保證合併後的cpp編譯通過,再加聯合編譯器一起用,最少能節省一半時間,我們遊戲項目1000個cpp編譯加鏈接5分鐘可以搞定
1. 使用make -j4 windows下也有類似的方法
2. 盡量不要用模版和宏,這兩個玩意最占編譯時間。
想到了再更。少用模版
說一個我自己的實踐
1、Windows 平台,使用increase build ,缺點是無法產生pdb 符號文件。速度有保障2、Linux平台,最近發現一個很有趣的現象,我們寫了一個腳本把所有的cpp 文件寫到了一個CPP 文件中,可以大幅度提高編譯速度,缺點是gdb 調試的時候不方便。使用distcc 和ccache 並不能顯著提高速度,除非機器數量特別龐大,而且要保證機器環境一致,相比之下更推薦寫腳本把CPP 文件數量減少。上面很多有說pimpl的,主要作用在於編譯分離,其實是增加了編碼量以及初次編譯時長,增量編譯才體現作用。
補充一下,還有一個辦法。就是想JUCE庫一樣,把所有的.cpp文件include到一個.cpp文件,然後只編譯這一個文件。
IncrediBuild 同時編譯的機器足夠多的時候快到不敢相信。 不過這個不能改善鏈接速度... ... 我們之前買了兩台8核的機器做伺服器, 同時也做分散式編譯終端... ..
1.選一個更快的編譯器,比如clang比gcc要快2.編譯緩存,比如ccache3.並行編譯,主要是不同模塊可以同時編譯
推薦閱讀:
※C++中,如何在標準庫的std::string和常用庫(Qt,VC等)的QString之間進行選擇?
※微軟vector類中resize函數的實現對比linux是不是不夠好?
※**p[] 和*(*p)[] 有什麼區別?
※C語言和C++的基礎知識區別大嗎?
※為什麼這段 c++ 代碼需要加這對括弧才正確運行,是編譯器問題嗎?