簡體   English   中英

GCC/Make 構建時間優化

[英]GCC/Make Build Time Optimizations

我們有使用 gcc 並制作文件的項目。 項目還包含一個大子項目 (SDK) 和許多使用 SDK 和一些共享框架的相對較小的子項目。

我們使用預編譯的頭文件,但這僅有助於重新編譯更快。

是否有任何已知的技術和工具可以幫助進行構建時優化? 或者,也許你知道一些關於這個或相關主題的文章/資源?

您可以從兩個方面解決這個問題:重構代碼以降低編譯器看到的復雜性,或者加快編譯器的執行速度。

無需接觸代碼,您就可以在其中添加更多的編譯能力。 使用 ccache 避免重新編譯您已經編譯的文件,並使用 distcc 在更多機器之間分配構建時間。 使用 make -j 其中 N 是內核數+1,如果你在本地編譯,或者更大的數字用於分布式構建。 該標志將並行運行多個編譯器。

重構代碼。 更喜歡前向聲明而不是包含(簡單)。 盡可能多地解耦以避免依賴(使用 PIMPL 習慣用法)。

模板實例化很昂貴,它們在每個使用它們的編譯單元中重新編譯。 如果您可以重構模板以轉發聲明它們,然后僅在一個編譯單元中實例化它們。

我能想到的最好的make-j選項。 這告訴make並行運行盡可能多的作業:

make -j

如果要將並發作業的數量限制為n ,可以使用:

make -j n


確保依賴項是正確的,這樣make就不會運行它不需要的作業。


另一件需要考慮的事情是gcc-O開關所做的優化。 您可以指定各種優化級別。 優化程度越高,編譯和鏈接時間越長。 我使用的一個項目需要 2 分鍾才能與-O3鏈接,半分鍾與-O1鏈接。 您應該確保您的優化沒有超出您的需要。 您可以在不優化開發構建和優化部署構建的情況下構建。


使用調試信息 ( gcc -g ) 進行編譯可能會增加可執行文件的大小並可能影響構建時間。 如果您不需要它,請嘗試刪除它以查看它是否會影響您。


鏈接的類型(靜態與動態)應該有所不同。 據我了解 static 鏈接需要更長的時間(盡管我在這里可能錯了)。 您應該看看這是否會影響您的構建。

從項目的描述中,我猜你每個目錄都有一個 Makefile 並且經常使用遞歸。 在這種情況下, “Recursive Make Considered Harmful”中的技術應該會很有幫助。

如果您有多台計算機可用 gcc 由distcc很好地分發。

此外,您還可以使用ccache

所有這些都只需要對 makefile 進行很少的更改即可。

此外,您可能希望使您的源代碼文件盡可能小且獨立/可行,即更喜歡許多較小的 object 文件而不是一個巨大的單個 object 文件。

這也將有助於避免不必要的重新編譯,此外,您可以為每個源代碼目錄或模塊擁有一個 object 文件的 static 庫,基本上允許編譯器盡可能多地重用以前編譯的代碼。

之前的任何回復中尚未提及的其他內容正在使符號鏈接盡可能“私有”,即,如果您的代碼不必在外部可見,則更喜歡 static 鏈接(函數、變量)。

此外,您可能還想研究使用GNU gold linker ,這對於為 ELF 目標編譯 C++ 代碼效率更高

基本上,我建議您仔細分析構建過程並檢查花費最多的時間,這將為您提供一些關於如何優化構建過程或項目源代碼結構的提示。

您可以考慮切換到不同的構建系統(顯然不適用於所有人),例如 SCons。 SCons 比 make 聰明得多。 它會自動掃描 header 依賴項,因此您始終擁有最小的重建依賴項集。 通過在 SConstruct 文件中添加Decider('MD5-timestamp')行,SCons 將首先查看文件的時間戳,如果它比之前構建的時間戳更新,它將使用文件的 MD5 來制作確定你確實改變了一些東西。 這不僅適用於源文件,也適用於 object 文件。 這意味着如果您更改評論,例如,您不必重新鏈接。

header 文件的自動掃描還確保我永遠不必鍵入 scons --clean。 它總是做正確的事。

使用小文件可能並不總是一個好的建議。 磁盤的最小扇區大小為 32 或 64K,文件至少占用一個扇區。 所以 1024 個 3K 大小的文件(內部的小代碼)實際上會占用 32 或 64 Meg 的磁盤空間,而不是預期的 3 meg。 需要由驅動器讀取的 32/64 meg。 如果文件分散在磁盤上,則尋道時間會增加讀取時間。 顯然,這對磁盤緩存有一定的幫助。 預編譯的 header 也可以很好地幫助緩解這種情況。

因此,考慮到編碼指南,將每個結構、類型定義或實用程序 class 放入單獨的文件中是沒有意義的。

如果您可以訪問多台機器,則可以使用distcc分布式編譯器來減少構建時間。 這是來自 IBM developerWorks 的一篇與 distcc 相關的文章以及如何使用它: http://www.ibm.com/developerworks/linux/library/l-distcc.html

另一種減少構建時間的方法是使用預編譯頭文件。 這是gcc 的起點

如果您的機器有多個 cpu/core(2x cores/cpus 的數量就可以了),也不要忘記在使用 make 構建時使用 -j。

如果您有一個帶有開發人員機器的 LAN,也許您應該嘗試實現一個分布式編譯器解決方案,例如distcc

如果構建過程中的所有時間都花在分析依賴關系或執行一些單一的串行任務上,這可能無濟於事。 對於將許多源文件編譯成 object 文件的原始緊縮,並行構建顯然有幫助,正如 Nathan 建議的(在單台機器上)。 跨多台機器並行化可以更進一步。

http://ccache.samba.org/ 大大加快了速度。

我從事一個中等規模的項目,這是我們加快編譯時間的唯一方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM