2010-01-15 27 views
15

我在linux上使用mingw32交叉編譯器構建了很多自動生成的代碼,其中包括一個特別大的文件(約15K行)。大多數文件非常快,但是這個大文件需要很長時間(約15分鐘)才能編譯。我如何知道爲什麼g ++在特定文件上花費很長時間?

我已經嘗試過操縱各種優化標誌,看看它們是否有任何效果,沒有任何運氣。我真正需要的是確定g ++在做什麼的一些方法,這需要花費很長時間。是否有任何(相對簡單的)方法讓g ++產生關於不同編譯階段的輸出,以幫助我縮小可能的掛斷?

不幸的是,我沒有能力重建這個交叉編譯器,因此向編譯器添加調試信息並逐步完成它並不是一種可能性。

什麼是文件:

  • 一堆包括
  • 一串字符串比較
  • 一堆的if-then檢查和構造函數調用

該文件是的工廠生產某種父母類別的許多不同特定的子類。然而,大部分的內容都沒有什麼特別的花哨。


-ftime報告的結果,由尼爾·巴特沃思的建議,表明了「生命分析」階段正在921秒,它佔據了大部分15分鐘。

看起來這發生在數據流分析過程中。該文件本身就是一堆條件字符串比較,通過以字符串形式提供的類名稱構造一個對象。

我們認爲改變它以指向函數指針的名稱映射可能會改善一點,所以我們將嘗試這樣做。


實際上,產生一串工廠函數(每個對象),並從原有的15分鐘產生從對象的字符串名稱的地圖的指針其工廠功能降低編譯時至約25秒,這將爲他們節省大量的時間。

再次感謝尼爾巴特沃斯關於-ftime-report的提示。

+0

看看這個:http://stackoverflow.com/questions/318398/why-does-c-compilation-take-so-long – 2010-01-15 15:04:39

+0

你能告訴我們什麼是在文件中?內聯函數?枚舉?定義?包括和宏列表?他們有多少人? – Coincoin 2010-01-15 15:18:49

+0

如果使用本地編譯器,是否會遇到同樣的問題?如果是這樣,您可以重新啓動配置文件,查看時間花費在哪裏。 – 2010-01-15 15:33:06

回答

24

不會給你想要的所有細節,但嘗試運行-v(詳細)和-ftime-report標誌。後者產生了編譯器所做的一個總結。

+0

-ftime-report是我需要的線索。 – Schamp 2010-01-20 21:47:20

3

它最有可能包括TONNES的包括。我相信-MD會列出給定CPP文件中的所有包含文件(包括包含內容等等)。

+0

++是的。嵌套包含和模板可以快速發送預處理程序。至少可以使用預編譯頭文件處理這些包括。 – 2010-01-15 20:16:15

2

什麼減慢g ++一般是模板。例如Boost喜歡使用它們。這意味着很好的代碼,很好的性能,但編譯速度很差。

另一方面,15分鐘看起來非常長。快速搜索後,似乎這是一個常見的問題,與明暗

+0

不是隻是mingw,我已經看到Linux gcc和Visual Studio的表現一樣糟糕,再次,它只是編譯了一次源代碼包,所以編譯器沒有機會加速它。 – luiscubal 2010-01-15 15:32:43

+0

@Tristram什麼是你的谷歌搜索字符串? – Schamp 2010-01-15 16:57:45

1

另一個嘗試的過程是將「進度標記」pragma s添加到您的代碼中,以捕獲需要很長時間的代碼部分。 Visual Studio編譯器提供#pragma message(),雖然沒有用於執行此操作的標準雜注。

將一個標記放在代碼的開頭,並在代碼的末尾放置一個標記。結束標記可能是#error,因爲您不關心源文件的其餘部分。相應地移動標記以捕獲花費最長時間的代碼部分。

只是一個想法...

1

我會使用#if 0/#endif以消除編譯源文件的大部分。重複使用不同的代碼塊,直到找到哪個塊緩慢爲止。對於初學者,您可以通過使用#if 0/#endif來排除除#include之外的所有內容,看看您的#include是否是問題。

0

與@Goz和@Josh_Kelley相關,您可以使用-E獲取gcc/g ++來預處理源代碼(使用#includes內聯)。這是確定您的來源有多大的一種方法。

如果編譯器本身存在問題,則可能需要對需要很長時間的編譯命令進行置位,以查看是否存在特定的文件訪問或需要很長時間的特定內部操作。

0

編譯器看到的是預處理器的輸出,所以單個源的大小不是一個好的度量,你必須考慮它包含的源文件和所有文件以及它們包含的文件等。實例化多種類型的模板會爲每種使用的單獨類型生成代碼,因此最終可能會產生大量代碼。例如,如果您已經爲許多類廣泛使用了STL容器。一個源代碼中的15K行相當多,但即使分裂,仍然需要編譯所有代碼;但是使用增量構建可能意味着它不需要全部編譯。真的不需要一個很大的文件;它只是很差的做法/設計。當一個文件達到500行時,我開始考慮更好的模塊化(雖然我不是教條)

0

編譯過程中需要注意的一件事是計算機有多少空閒空間。如果編譯器分配太多的內存以致計算機開始交換,編譯時間將會順利完成。

如果你看到這種情況發生,一個簡單的解決方案是安裝更多的RAM ......或者只是將文件拆分成可以單獨編譯的多個部分。