我正在使用g ++來編譯和鏈接一個包含大約15個C++源文件和4個共享目標文件的項目。最近鏈接時間增加了一倍多,但我沒有makefile的歷史記錄。有沒有什麼辦法來分析g ++來查看鏈接的哪個部分需要很長時間?使用gcc/g ++和ld連接配置文件的時間
編輯:在我注意到makefile始終在使用-O3優化之後,我設法將刪除該開關的時間減半。有沒有什麼好的方法可以在沒有反覆試驗的情況下找到它?
編輯:我真的沒有興趣分析如何工作。我很想知道如何將鏈接時間增加到特定的命令行開關或對象文件。
我正在使用g ++來編譯和鏈接一個包含大約15個C++源文件和4個共享目標文件的項目。最近鏈接時間增加了一倍多,但我沒有makefile的歷史記錄。有沒有什麼辦法來分析g ++來查看鏈接的哪個部分需要很長時間?使用gcc/g ++和ld連接配置文件的時間
編輯:在我注意到makefile始終在使用-O3優化之後,我設法將刪除該開關的時間減半。有沒有什麼好的方法可以在沒有反覆試驗的情況下找到它?
編輯:我真的沒有興趣分析如何工作。我很想知道如何將鏈接時間增加到特定的命令行開關或對象文件。
剖析g++
將徒勞無功,因爲g++
不執行鏈接,鏈接ld
一樣。
分析ld
也可能不會向您顯示任何有趣的內容,因爲鏈接時間通常由磁盤I/O占主導地位,並且如果您的鏈接不是,您將不知道如何處理分析數據,除非你明白ld
內部。
如果您的鏈接時間只有鏈接中的15個文件顯而易見,那麼您的開發系統可能有問題[1];要麼是它有一塊磁盤在不斷重試,或者你沒有足夠的內存來執行鏈接(鏈接往往是內存密集型),並且你的系統會像瘋了一樣交換。
假設您使用的是基於ELF的系統,那麼您也可以嘗試使用新的gold
鏈接器(binutils的一部分),該鏈接器通常比GNU ld
快幾倍。我的典型鏈接涉及1000個對象,產生200多MB的可執行文件,並在不到60秒的時間內完成。
如果你剛剛達到內存限制,你可能會聽到磁盤工作,系統活動監視器會告訴你。但是如果鏈接仍然是CPU綁定的(即,如果CPU使用率仍然很高),那不是問題。如果鏈接是IO綁定的,最常見的罪魁禍首可以是運行時信息。無論如何看看可執行文件的大小。
要以不同的方式回答您的問題:您是否在使用沉重的模板?對於具有不同類型參數的模板的每種用法,將生成整個模板的新實例,以便您爲鏈接器獲得更多工作。然而,爲了使這一點真正引人注目,你需要使用一些非常重要的模板庫。來自Boost項目的許多資格 - 當使用具有複雜語法的Boost :: Spirit時,我得到了基於模板的代碼膨脹。大約4000行代碼被編譯爲7,7M的可執行文件 - 更改一行代碼所需的專業化數量和最終可執行文件的大小增加了一倍。然而,內聯幫助了很多,導致了1,9M的產出。
共享庫可能會導致其他問題,您可能需要查看-fvisibility = hidden的文檔,無論如何它都會改善您的代碼。從-fvisibility GCC手冊:
Using this feature can very substantially improve linking and load times of shared object libraries, produce more optimized code, provide near-perfect API export and prevent symbol clashes. It is *strongly* recommended that you use this in any shared objects you distribute.
實際上,鏈接器通常必須支持用於應用或其他的庫覆蓋定義到庫符號的可能性,而通常這是不期望的用法。請注意,使用它不是免費的,但它確實需要(微不足道的)代碼更改。
該文檔建議的鏈接是:http://gcc.gnu.org/wiki/Visibility