C++ 鏈接時間過長,如何找到原因?
01-14
C++鏈接時間過長,我想知道是花在什麼地方了,然後針對它進行優化。
補充一下我的具體情況:1. 硬體環境不考慮,開發機配置蠻好的,用的SSD。2. 軟體環境是windows7, vs2013.3. 我們曾經遇到這樣一種情況:
a. 在某個CPP中,調用了大約100個不同class的函數(因為是用宏實現的),當時debug的鏈接時間約為6分鐘,release的鏈接時間達到了15分鐘。 b. 我嘗試新寫一個函數來代替宏(因為這些class都是某個基類的子類,恰好這個函數又是虛方法),debug時間縮短為2分鐘,release時間縮短到3分鐘。對工作流程來說是巨大的優化。 情況大概是這樣:==================== 以前: #include "A.h" #include "B.h" #include "C.h" ...#define CALL_FUNC(MyClass) {MyClass* pObj = new MyClass; pObj-&>Func();} CALL_FUNC(A) CALL_FUNC(B) CALL_FUNC(C) ...===================== 優化後: #include "A.h" #include "B.h" #include "C.h"
... void CallFunc(MyClassBase* pObject) { pObject-&>Func(); } #define CALL_FUNC(MyClass) {MyClass* pObj = new MyClass; CallFunc(pObject);} CALL_FUNC(A) CALL_FUNC(B) CALL_FUNC(C)c. 事後我分析了一下原因,也許在那個CPP里,因為調用的符號太多,所以導致連接很慢,當我改用一個統一的基類以後,實際上符號就都統一成一個了。4. Release 的鏈接配置為: References Yes(/OPT:REF)Enable COMDAT Folding Yes(/OPT:ICF)Link Time Code Generation: Use Link Time Code Generation (/LTCG)最後一個選項貌似很有講究,我也谷歌了一下,不明就裡。也不太清楚release這樣配置鏈接是否合理。
先排除那些硬體問題,比如沒用ssd硬碟,cpu太慢等等,再排除那些不該輕易打開的編譯選項,特別是link time optimization系列,還是慢的話,介紹一個思路。
以前在使用vc的遊戲項目做過一個proj的link時間優化,從9s優化到5s,link時間如何查看可以參考其他同學回復,vc有選項,不贅述。思路來自這裡,走過路過不要錯過,用力收藏之
http://nedbatchelder.com/blog/200401/speeding_c_links.html就是減少編譯器生成的export function數量,來降低link時間。經驗教訓就是header文件不要圖方便隨便include。這裡有些當時的筆記stats,懶得做特別排版了,隨便看看我的具體做法,就是修改代碼,把很多inline函數移掉,或者重新組織項目結構,來加速編譯。
Before Opt:
36462 functions 9.2s1st Opt:
Remove many inline functions, mainly in meta info system 25710 functions8.5s
2nd Opt:
Move CommonSkillTable to CommonResource project, thus many inline functions have been moved. Compiler can save time on resolving unique copies of these functions 13246 functions 6.5s3rd Opt:
Move QuestTable and BuffTable to CommonResource project 10934 functions 5.9s4th Opt:
Remove speedtree header file in the QSLevel.h So many speedtree related functions are removed. 661 Functions left 5.1s這個問題好像挺少見的,我現在想出來的方式是可以Dump出所有的Symbols(如Linux下的objdump, nm, Windows平台的DumpBin等),然後再進行Symbol分析,如size, count等。
環境說一下,是vs的link還是linux的ld?是debug版還是release版本?關閉各種優化是否依然很慢?磁碟io效率如何?
如果是visual studio:Tools -&> Options -&> Projects and Solutions -&> VC++ Project Settings -&> Build Timing
說個我遇到的場景:
當你的項目含有多個static library而這些static library又包含了大量重複符號的時候。
比如:lib 1 用了 大量STL , lib 2 也用了 大量STL, 並且都用了很普遍的具現化,例如 std::vector&Link-Time Optimization(LTO)之類的技術,會在鏈接器被調用的時候,做類似編譯器的工作,而C++的編譯是出了名的慢,結果就是這樣。
解決方法:平時開發時不要打開類似Link-Time Optimization(LTO)之類的技術,只在最後準備發布的時候打開(當然測試工作要保證最後生成的代碼是正確的)。你最後說的Link Time Code Generation(/LTCG)可能就是類似LTO的技術。盧兄,多給點信息嘛,vs里可以打開鏈接過程查看,不過一切查找終將在ssd里灰飛煙滅
推薦閱讀:
※C 語言比 C++ 更強大嗎?
※如何評價 C++14 ?
※【for(int i=10, j=1; i=j=0; i++, j--)()】將循環幾次?
※無編程基礎,跳過C直接學C++,壞處是學習難度陡峭,還是會有知識缺陷,還是二者都有?