如何分析和提高大型項目(C/C++)的編譯速度?


常見的有幾個:

1. Precompile header

2. 多線程編譯

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、內存虛擬磁碟,純內存IO

3、增量編譯

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.編譯緩存,比如ccache

3.並行編譯,主要是不同模塊可以同時編譯


推薦閱讀:

C++中,如何在標準庫的std::string和常用庫(Qt,VC等)的QString之間進行選擇?
微軟vector類中resize函數的實現對比linux是不是不夠好?
**p[] 和*(*p)[] 有什麼區別?
C語言和C++的基礎知識區別大嗎?
為什麼這段 c++ 代碼需要加這對括弧才正確運行,是編譯器問題嗎?

TAG:C編程語言 | C | GCC | VisualC | LLVM |