簡體   English   中英

將源代碼合並到單個文件中進行優化

[英]Combining source code into a single file for optimization

我的目標是減小C項目可執行文件的大小,並嘗試了所有編譯器/鏈接器選項,這些選項在一定程度上有所幫助。 我的代碼包含許多單獨的文件。 我的問題是將所有源代碼合並到一個文件中是否可以幫助實現我所希望的優化? 我在某處讀到,如果編譯器在單個文件中找到所有代碼而不是單獨的多個文件,則它將更好地優化。 真的嗎?

當編譯器在同一可編譯(* .c)文件中找到所需的代碼時,確實可以更好地進行優化。 如果您的程序長於1000行左右,您可能會后悔將所有代碼放在一個文件中,因為這樣做會使您的程序難以維護,但是如果少於500行,則可以嘗試一個文件,然后看看是否有幫助。

關鍵的考慮因素是一個可編譯文件調用中的代碼多久使用一次,或者使用另一個對象中定義的對象(包括函數)。 如果跨此邊界的控制轉移很少,則擦除邊界將無濟於事。 因此,在進行性能編碼時,關鍵是將緊密相關的代碼放在同一文件中。

我非常喜歡你的問題。 我認為這是一個正確的問題。 而且,盡管完整的答案還不夠簡單,不足以在Stackexchange答案中充分對待,但您對答案的追求將為您帶來很多啟發。 盡管您可能尚未意識到,但是您的問題確實涉及鏈接,這是每個高級程序員最終都必須學習的主題。 您的問題涉及符號表,內聯,返回值的就地構造以及其他一些細微的因素。

無論如何,如果您的程序短於500行左右,那么嘗試單文件方法幾乎不會造成任何損失。 如果超過1000行,則不建議使用單個文件。

這取決於編譯器。 例如,英特爾C ++ Composer XE可以自動對多個文件進行優化(分別在linux / windows中使用icc -fast *.c *.cppicl /fast *.c *.cpp進行構建時)。

當您使用Microsoft Visual Studio或派生產品(例如用於微控制器的Atmel Studio)時,每個源文件都是自己編譯的(即,為項目中的每個ccpp文件發出一個cliclgcc命令) 。 這意味着沒有優化。

對於微控制器項目,有時必須將所有內容放在一個文件中,以使其甚至適合控制器上有限的閃存。 如果您的編譯器/ IDE與Visual Studio一樣,可以使用一個技巧:選擇所有源文件,並使它們不參與構建過程(但將它們留在項目中),然后創建一個文件(我始終使用whole_program.c#include每個單獨的源(即非標頭)文件(請注意,包括c文件的內容已被許多高級程序員所反對,但是有時,您必須以骯臟的方式進行操作,而對於微控制器,實際上往往更多)。

我的經驗是,使用gnu / gcc進行的優化位於單個文件內,並且包括創建單個對象的內容。 使用clang / llvm非常容易,我建議不要優化clang步驟,使用clang從C到字節碼,使用llvm-link將所有字節碼模塊鏈接到一個字節碼模塊中,然后就可以優化整個項目中,所有源文件一起進行了優化,LLC朝目標方向添加了更多優化。 最好的結果是使用三重命令行選項告訴clang最終目標是什么。 為了使gnu路徑執行相同的操作,要么使用將一個大文件編譯為一個對象,要么使用機器代碼級優化器,而不執行鏈接器的其他操作,那么這將是必須要做的。 也許gnu具有公開的ir文件格式,優化程序和ir到目標工具,但是我想我現在已經知道了。

我的許多項目http://github.com/dwelch67 ,盡管程序非常簡單,但它們具有針對同一源文件的llvm和gnu構建,您可以看到llvm的構建位置,我是根據未優化的字節碼和優化的字節碼制作二進制文件的( llvm的優化器在while循環較小時會出現問題,有時會生成無法正常工作的代碼,一種非常快速的檢查方法是嘗試使用未經優化的llvm二進制文件和gnu二進制文件,以查看它們是否都具有相同的功能(您)或僅優化的llvm不起作用(它們))。

暫無
暫無

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

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