GCC 編譯最佳化指南【轉】

來源:互聯網
上載者:User

標籤:使用率   時間   無法   傳遞   stack   function   gcc   ide   ret   

轉自:http://www.jinbuguo.com/linux/optimize_guide.html

著作權聲明

本文作者是一位開源理念的堅定支援者,所以本文雖然不是軟體,但是遵照開源的精神發布。

  • 無擔保:本文作者不保證作品內容準確無誤,亦不承擔任何由於使用此文檔所導致的損失。
  • 自由使用:任何人都可以自由的閱讀/連結/列印此文檔,無需任何附加條件。
  • 名譽權:任何人都可以自由的轉載/引用/再創作此文檔,但必須保留作者署名並註明出處。
其他作品

本文作者十分願意與他人分享勞動成果,如果你對我的其他翻譯作品或者技術文章有興趣,可以在如下位置查看現有的作品集:

  • 金步國作品集 [ http://www.jinbuguo.com/ ]
連絡方式

由於作者水平有限,因此不能保證作品內容準確無誤。如果你發現了作品中的錯誤(哪怕是錯別字也好),請來信指出,任何提高作品品質的建議我都將虛心接納。

  • Email(QQ):70171448在QQ郵箱
前言

網上關於編譯最佳化的文章很多,但大多零零散散,不成體系,本文試圖給出一個完整和清晰的最佳化思路,同時提供在實踐中如何進行最佳化的詳盡參考。但是,在介紹所有最佳化知識之前首先引用LFS-Book中的一句忠告:“使用編譯器最佳化得到的小幅度效能提升,與它帶來的風險相比微不足道”。你還要進行最佳化嗎?

%@&#=^%~*# ... 
OK, crazy guy! Let‘s Go!!

在繼續之前,作者還是奉勸各位:如果追求極致的最佳化,那麼它將是一件既耗時又麻煩的事情,你會陷入無止盡的測試、測試、再測試……另外 Gentoo wiki 上有這麼一句話:"GCC has well over a hundred individual optimization flags and it would be insane to try and describe them all."所以本文不會涉及全部GCC最佳化選項。最後作者還是再羅唆一句:最佳化應當適可而止為好,將精力留出來做一些其它事情會更有意義!

先決條件

本文的主要讀者是 LFS/Gentoo 的玩家,基本上比較 crazy 的玩家都接觸過,如果你之前從未使用過 LFS/Gentoo ,請先按照《Linux From Scratch 6.2 中文版》做一遍 LFS ,然後再來閱讀此文將會更有意義。另外,本文是建立在《深入理解軟體包的配置、編譯與安裝》一文基礎之上的,在開始閱讀本文之前,請先閱讀它。

基本原理

我們首先從三個方面來看與最佳化相關的內容:

  1. 從運行時的依賴關係來看,對效能有較大影響的組件有 kernel 和 glibc ,雖然這嚴格說來這不屬於本文的話題,但是經過精心選擇、精心配置、精心編譯的核心與C庫將對提高系統的運行速度起著基礎性的作用。
  2. 從被編譯的軟體包來看,每個軟體包的 configure 指令碼都提供了許多配置選項,其中有許多選項是與效能息息相關的。比如,對於 Apache-2.2.6 而言,你可以使用 --enable-MODULE=static 將模組靜態編譯進核心,使用 --disable-MODULE 禁用不需要的模組,使用 --with-mpm=MPM 選擇一個高效的多路處理模組,在不需要IPv6的情況下使用 --disable-ipv6 禁用IPv6支援,在不使用線程化的MPM時使用 --disable-threads 禁用線程支援,等等……這部分內容顯然不可能在本文中進行完整的講述,本文只能講述與最佳化相關的通用選項。針對特定的軟體包,請在編譯前使用 configure --help 查看所有選項,並精心選擇。
  3. 從編譯過程自身來看,將原始碼編譯為二進位檔案是在 Makefile 檔案的指導下,由 make 程式調用一條條編譯命令完成的。而將原始碼編譯為二進位檔案又需要經過以下四個步驟:預先處理(cpp) → 編譯(gcc或g++) → 彙編(as) → 串連(ld) ;括弧中表示每個階段所使用的程式,它們分別屬於 GCC 和 Binutils 軟體包。顯然的,最佳化應當從編譯工具自身的選擇以及控制編譯工具的行為入手。

大體上編譯最佳化就這"三板斧"(其實是"三腳貓")了,本文接下來的內容將討論這隻貓的後兩隻腳。

編譯工具的選擇

對於編譯工具自身的選擇,在假定使用 Binutils 和 GCC 以及 Make 的前提下,沒什麼好說的,基本上新版本都能帶來效能提升,同時比老版本對新硬體的支援更好,所以應當盡量選用新版本。不過追新也可能帶來系統的不穩定,這就要針對實際情況進行權衡了。本文以 Binutils-2.18 和 GCC-4.2.2/GCC-4.3.0 以及 Make-3.81 為例進行說明。

configure 選項

這裡我們只講解通用的"體繫結構選項",由於"特性選項"在每個軟體包之間千差萬別,所以不可能在此處進行講解。

這部分內容很簡單,並且其含義也是不言而喻的,下面只列出常用的值:

  • i586-pc-linux-gnu
  • i686-pc-linux-gnu
  • x86_64-pc-linux-gnu
  • powerpc-unknown-linux-gnu
  • powerpc64-unknown-linux-gnu

如果你實在不知道應當使用哪一個,那麼就乾脆不使用這幾個選項,讓 config.guess 指令碼自己去猜吧,反正也挺準的。

編譯選項

讓我們先看看 Makefile 規則中的編譯命令通常是怎麼寫的。

大多數軟體包遵守如下約定俗成的規範:

#1,首先從原始碼產生目標檔案(預先處理,編譯,彙編),"-c"選項表示不執行連結步驟。$(CC) $(CPPFLAGS) $(CFLAGS) example.c   -c   -o example.o#2,然後將目標檔案串連為最終的結果(串連),"-o"選項用於指定輸出檔案的名字。$(CC) $(LDFLAGS) example.o   -o example#有一些軟體包一次完成四個步驟:$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) example.c   -o example

當然也有少數軟體包不遵守這些約定俗成的規範,比如:

#1,有些在命令列中漏掉應有的Makefile變數(注意:有些遺漏是故意的)$(CC) $(CFLAGS) example.c    -c   -o example.o$(CC) $(CPPFLAGS) example.c  -c   -o example.o$(CC) example.o   -o example$(CC) example.c   -o example#2,有些在命令列中增加了不必要的Makefile變數$(CC) $(CFLAGS) $(LDFLAGS) example.o   -o example$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) example.c   -c   -o example.o

當然還有極個別軟體包完全是"胡來":亂用變數(增加不必要的又漏掉了應有的)者有之,不用$(CC)者有之,不一而足.....

儘管將原始碼編譯為二進位檔案的四個步驟由不同的程式(cpp,gcc/g++,as,ld)完成,但是事實上 cpp, as, ld 都是由 gcc/g++ 進行間接調用的。換句話說,控制了 gcc/g++ 就等於控制了所有四個步驟。從 Makefile 規則中的編譯命令可以看出,編譯工具的行為全靠 CC/CXX CPPFLAGS CFLAGS/CXXFLAGS LDFLAGS 這幾個變數在控制。當然理論上控制編譯工具行為的還應當有 AS ASFLAGS ARFLAGS 等變數,但是實踐中基本上沒有軟體包使用它們。

那麼我們如何控制這些變數呢?一種簡易的做法是首先設定與這些 Makefile 變數同名的環境變數並將它們 export 為全域,然後運行 configure 指令碼,大多數 configure 指令碼會使用這同名的環境變數代替 Makefile 中的值。但是少數 configure 指令碼並不這樣做(比如GCC-3.4.6和Binutils-2.16.1的指令碼就不傳遞LDFLAGS),你必須手動編輯產生的 Makefile 檔案,在其中尋找這些變數並修改它們的值,許多源碼包在每個子檔案夾中都有 Makefile 檔案,真是一件很累人的事!

CC 與 CXX

這是 C 與 C++ 編譯器命令。預設值一般是 "gcc" 與 "g++"。這個變數本來與最佳化沒有關係,但是有些人因為擔心軟體包不遵守那些約定俗成的規範,害怕自己苦心設定的 CFLAGS/CXXFLAGS/LDFLAGS 之類的變數被忽略了,而索性將原本應當放置在其它變數中的選項一股老兒塞到 CC 或 CXX 中,比如:CC="gcc -march=k8 -O2 -s"。這是一種怪異的用法,本文不提倡這種做法,而是提倡按照變數本來的含義使用變數。

CPPFLAGS

這是用於預先處理階段的選項。不過能夠用於此變數的選項,看不出有哪個與最佳化相關。如果你實在想設一個,那就使用下面這兩個吧:

-DNDEBUG
"NDEBUG"是一個標準的 ANSI 宏,表示不進行調試編譯。
-D_FILE_OFFSET_BITS=64
大多數包使用這個來提供大檔案(>2G)支援。
CFLAGS 與 CXXFLAGS

CFLAGS 表示用於 C 編譯器的選項,CXXFLAGS 表示用於 C++ 編譯器的選項。這兩個變數實際上涵蓋了編譯和彙編兩個步驟。大多數程式和庫在編譯時間預設的最佳化層級是"2"(使用"-O2"選項)並且帶有偵錯符號來編譯,也就是 CFLAGS="-O2 -g", CXXFLAGS=$CFLAGS 。事實上,"-O2"已經啟用絕大多數安全的最佳化選項了。另一方面,由於大部分選項可以同時用於這兩個變數,所以僅在最後講述只能用於其中一個變數的選項。[提醒]下面所列選項皆為非預設選項,你只要按需添加即可。

先說說"-O3"在"-O2"基礎上增加的幾項:

-finline-functions
允許編譯器選擇某些簡單的函數在其被調用處展開,比較安全的選項,特別是在CPU二級緩衝較大時建議使用。
-funswitch-loops
將迴圈體中不改變值的變數移動到迴圈體之外。
-fgcse-after-reload
為了清除多餘的溢出,在重載之後執行一個額外的載入消除步驟。

另外:

-fomit-frame-pointer
對於不需要棧指標的函數就不在寄存器中儲存指標,因此可以忽略儲存和檢索地址的代碼,同時對許多函數提供一個額外的寄存器。所有"-O"層級都開啟它,但僅在調試器可以不依靠棧指標運行時才有效。在AMD64平台上此選項預設開啟,但是在x86平台上則預設關閉。建議顯式的設定它。
-falign-functions=N
-falign-jumps=N
-falign-loops=N
-falign-labels=N
這四個對齊選項在"-O2"中開啟,其中的根據不同的平台N使用不同的預設值。如果你想指定不同於預設值的N,也可以單獨指定。比如,對於L2-cache>=1M的cpu而言,指定 -falign-functions=64 可能會獲得更好的效能。建議在指定了 -march 的時候不明確指定這裡的值。

調試選項:

-fprofile-arcs
在使用這一選項編譯器並運行它以建立包含每個代碼塊的執行次數的檔案後,程式可以再次使用 -fbranch-probabilities 編譯,檔案中的資訊可以用來最佳化那些經常選取的分支。如果沒有這些資訊,gcc將猜測哪個分支將被經常運行以進行最佳化。這類最佳化資訊將會存放在一個以源檔案為名字的並以".da"為尾碼的檔案中。

全域選項:

-pipe
在編譯過程的不同階段之間使用管道而非臨時檔案進行通訊,可以加快編譯速度。建議使用。

目錄選項:

--sysroot=dir
將dir作為邏輯根目錄。比如編譯器通常會在 /usr/include 和 /usr/lib 中搜尋標頭檔和庫,使用這個選項後將在 dir/usr/include 和 dir/usr/lib 目錄中搜尋。如果使用這個選項的同時又使用了 -isysroot 選項,則此選項僅作用於庫檔案的搜尋路徑,而 -isysroot 選項將作用於標頭檔的搜尋路徑。這個選項與最佳化無關,但是在 CLFS 中有著神奇的作用。

代碼產生選項:

-fno-bounds-check
關閉所有對數組訪問的邊界檢查。該選項將提高數組索引的效能,但當超出數組邊界時,可能會造成不可接受的行為。
-freg-struct-return
如果struct和union足夠小就通過寄存器返回,這將提高較小結構的效率。如果不夠小,無法容納在一個寄存器中,將使用記憶體返回。建議僅在完全使用GCC編譯的系統上才使用。
-fpic
產生可用於共用庫的位置獨立代碼。所有的內部定址均通過全域位移表完成。要確定一個地址,需要將代碼自身的記憶體位置作為表中一項插入。該選項產生可以在共用庫中存放並從中載入的目標模組。
-fstack-check
為防止程式棧溢出而進行必要的檢測,僅在多線程環境中運行時才可能需要它。
-fvisibility=hidden
設定預設的ELF鏡像中符號的可見度為隱藏。使用這個特性可以非常充分的提高串連和載入共用庫的效能,產生更加最佳化的代碼,提供近乎完美的API輸出和防止符號碰撞。我們強烈建議你在編譯任何共用庫的時候使用該選項。參見 -fvisibility-inlines-hidden 選項。

硬體體繫結構相關選項[僅僅針對x86與x86_64]:

-march=cpu-type
為特定的cpu-type編譯二進位代碼(不能在更低層級的cpu上運行)。Intel可以用:pentium2, pentium3(=pentium3m), pentium4(=pentium4m), pentium-m, prescott, nocona, core2(GCC-4.3新增) 。AMD可以用:k6-2(=k6-3), athlon(=athlon-tbird), athlon-xp(=athlon-mp), k8(=opteron=athlon64=athlon-fx)
-mfpmath=sse
P3和athlon-xp層級及以上的cpu支援"sse"標量浮點指令。僅建議在P4和K8以上層級的處理器上使用該選項。
-malign-double
將double, long double, long long對齊於雙位元組邊界上;有助於產生更高速的代碼,但是程式的尺寸會變大,並且不能與未使用該選項編譯的程式一起工作。
-m128bit-long-double
指定long double為128位,pentium以上的cpu更喜歡這種標準,並且符合x86-64的ABI標準,但是卻不附合i386的ABI標準。
-mregparm=N
指定用於傳遞整數參數的寄存器數目(預設不使用寄存器)。0<=N<=3 ;注意:當N>0時你必須使用同一參數重新構建所有的模組,包括所有的庫。
-msseregparm
使用SSE寄存器傳遞float和double參數和傳回值。注意:當你使用了這個選項以後,你必須使用同一參數重新構建所有的模組,包括所有的庫。
-mmmx
-msse
-msse2
-msse3
-m3dnow
-mssse3(沒寫錯!GCC-4.3新增)
-msse4.1(GCC-4.3新增)
-msse4.2(GCC-4.3新增)
-msse4(含4.1和4.2,GCC-4.3新增)
是否使用相應的擴充指令集以及內建函數,按照自己的cpu選擇吧!
-maccumulate-outgoing-args
指定在函數引導段中計算輸出參數所需最大空間,這在大部分現代cpu中是較快的方法;缺點是會明顯增加二進位檔案尺寸。
-mthreads
支援Mingw32的安全執行緒異常處理。對於依賴於安全執行緒異常處理的程式,必須啟用這個選項。使用這個選項時會定義"-D_MT",它將包含使用選項"-lmingwthrd"串連的一個特殊的線程輔助庫,用於為每個線程清理異常處理資料。
-minline-all-stringops
預設時GCC只將確定目的地會被對齊在至少4位元組邊界的字串操作內聯進程式碼。該選項啟用更多的內聯並且增加二進位檔案的體積,但是可以提升依賴於高速 memcpy, strlen, memset 操作的程式的效能。
-minline-stringops-dynamically
GCC-4.3新增。對未知尺寸字串的小塊操作使用內聯代碼,而對大塊操作仍然調用庫函數,這是比"-minline-all-stringops"更聰明的策略。決定策略的演算法可以通過"-mstringop-strategy"控制。
-momit-leaf-frame-pointer
不為葉子函數在寄存器中儲存棧指標,這樣可以節省寄存器,但是將會使調試變的困難。注意:不要與 -fomit-frame-pointer 同時使用,因為會造成代碼效率低下。
-m64
產生專門運行於64位環境的代碼,不能運行於32位環境,僅用於x86_64[含EMT64]環境。
-mcmodel=small
[預設值]程式和它的符號必須位於2GB以下的地址空間。指標仍然是64位。程式可以靜態串連也可以動態串連。僅用於x86_64[含EMT64]環境。
-mcmodel=kernel
核心運行於2GB地址空間之外。在編譯linux核心時必須使用該選項!僅用於x86_64[含EMT64]環境。
-mcmodel=medium
程式必須位於2GB以下的地址空間,但是它的符號可以位於任何地址空間。程式可以靜態串連也可以動態串連。注意:共用庫不能使用這個選項編譯!僅用於x86_64[含EMT64]環境。

其它最佳化選項:

-fforce-addr
必須將地址複製到寄存器中才能對他們進行運算。由於所需地址通常在前面已經載入到寄存器中了,所以這個選項可以改進代碼。
-finline-limit=n
對偽指令數超過n的函數,編譯器將不進行內聯展開,預設為600。增大此值將增加編譯時間和編譯記憶體用量並且產生的二進位檔案體積也會變大,此值不宜太大。
-fmerge-all-constants
試圖將跨編譯單元的所有常量值和數組合并在一個副本中。但是標準C/C++要求每個變數都必須有不同的儲存位置,所以該選項可能會導致某些不相容的行為。
-fgcse-sm
在全域公用子運算式消除之後運行儲存移動,以試圖將儲存移出迴圈。gcc-3.4中曾屬於"-O2"層級的選項。
-fgcse-las
在全域公用子運算式消除之後消除多餘的在儲存到同一儲存地區之後的載入操作。gcc-3.4中曾屬於"-O2"層級的選項。
-floop-optimize
已廢除(GCC-4.1曾包含在"-O1"中)。
-floop-optimize2
使用改進版本的迴圈最佳化器代替原來"-floop-optimize"。該最佳化器將使用不同的選項(-funroll-loops, -fpeel-loops, -funswitch-loops, -ftree-loop-im)分別控制迴圈最佳化的不同方面。目前這個新版本的最佳化器尚在開發中,並且產生的程式碼品質並不比以前的版本高。已廢除,僅存在於GCC-4.1之前的版本中。
-funsafe-loop-optimizations
假定迴圈不會溢出,並且迴圈的允出準則不是無窮。這將可以在一個比較廣的範圍內進行迴圈最佳化,即使最佳化器自己也不能斷定這樣做是否正確。
-fsched-spec-load
允許一些裝載指令執行一些投機性的動作。
-ftree-loop-linear
在trees上進行線型迴圈轉換。它能夠改進緩衝效能並且允許進行更進一步的迴圈最佳化。
-fivopts
在trees上執行歸納變數最佳化。
-ftree-vectorize
在trees上執行迴圈向量化。
-ftracer
執行尾部複製以擴大超級塊的尺寸,它簡化了函數控制流程,從而允許其它的最佳化措施做的更好。據說挺有效。
-funroll-loops
僅對迴圈次數能夠在編譯時間或運行時確定的迴圈進行展開,產生的程式碼尺寸將變大,執行速度可能變快也可能變慢。
-fprefetch-loop-arrays
產生數組預讀取指令,對於使用巨大數組的程式可以加快代碼執行速度,適合資料庫相關的大型軟體等。具體效果如何取決於代碼。
-fweb
建立經常使用的緩衝器網路,提供更佳的緩衝器使用率。gcc-3.4中曾屬於"-O3"層級的選項。
-ffast-math
違反IEEE/ANSI標準以提高浮點數計算速度,是個危險的選項,僅在編譯不需要嚴格遵守IEEE規範且浮點計算密集的程式考慮採用。
-fsingle-precision-constant
將浮點常量作為單精確度常量對待,而不是隱式地將其轉換為雙精確度。
-fbranch-probabilities
在使用 -fprofile-arcs 選項編譯器並執行它來建立包含每個代碼塊執行次數的檔案之後,程式可以利用這一選項再次編譯,檔案中所產生的資訊將被用來最佳化那些經常發生的分支代碼。如果沒有這些資訊,gcc將猜測那一分支可能經常發生並進行最佳化。這類最佳化資訊將會存放在一個以源檔案為名字的並以".da"為尾碼的檔案中。
-frename-registers
試圖驅除代碼中的假依賴關係,這個選項對具有大量寄存器的機器很有效。gcc-3.4中曾屬於"-O3"層級的選項。
-fbranch-target-load-optimize
-fbranch-target-load-optimize2
在執行序啟動以及結尾之前執行分支目標緩衝器載入最佳化。
-fstack-protector
在關鍵函數的堆棧中設定保護值。在返回地址和傳回值之前,都將驗證這個保護值。如果出現了緩衝區溢位,保護值不再匹配,程式就會退出。程式每次運行,保護值都是隨機的,因此不會被遠程猜出。
-fstack-protector-all
同上,但是在所有函數的堆棧中設定保護值。
--param max-gcse-memory=xxM
執行GCSE最佳化使用的最大記憶體量(xxM),太小將使該最佳化無法進行,預設為50M。
--param max-gcse-passes=n
執行GCSE最佳化的最大迭代次數,預設為 1。

傳遞給彙編器的選項:

-Wa,options
options是一個或多個由逗號分隔的可以傳遞給彙編器的選項列表。其中的每一個均可作為命令列選項傳遞給彙編器。
-Wa,--strip-local-absolute
從輸出符號表中移除局部絕對符號。
-Wa,-R
合并資料區段和本文段,因為不必在資料區段和程式碼片段之間轉移,所以它可能會產生更短的地址移動。
-Wa,--64
設定字長為64bit,僅用於x86_64,並且僅對ELF格式的目標檔案有效。此外,還需要使用"--enable-64-bit-bfd"選項編譯的BFD支援。
-Wa,-march=CPU
按照特定的CPU進行最佳化:pentiumiii, pentium4, prescott, nocona, core, core2; athlon, sledgehammer, opteron, k8 。

僅可用於 CFLAGS 的選項:

-fhosted
按宿主環境編譯,其中需要有完整的標準庫,入口必須是main()函數且具有int型的傳回值。核心以外幾乎所有的程式都是如此。該選項隱含設定了 -fbuiltin,且與 -fno-freestanding 等價。
-ffreestanding
按獨立環境編譯,該環境可以沒有標準庫,且對main()函數沒有要求。最典型的例子就是作業系統核心。該選項隱含設定了 -fno-builtin,且與 -fno-hosted 等價。

僅可用於 CXXFLAGS 的選項:

-fno-enforce-eh-specs
C++標準要求強制檢查異常違例,但是該選項可以關閉違例檢查,從而減小產生代碼的體積。該選項類似於定義了"NDEBUG"宏。
-fno-rtti
如果沒有使用‘dynamic_cast‘和‘typeid‘,可以使用這個選項禁止為包含虛方法的類產生運行時表示代碼,從而節約空間。此選項對於異常處理無效(仍然按需產生rtti代碼)。
-ftemplate-depth-n
將最大模版執行個體化深度設為‘n‘,符合標準的程式不能超過17,預設值為500。
-fno-optional-diags
禁止輸出診斷訊息,C++標準並不需要這些訊息。
-fno-threadsafe-statics
GCC自動在訪問C++局部靜態變數的代碼上加鎖,以保證安全執行緒。如果你不需要安全執行緒,可以使用這個選項。
-fvisibility-inlines-hidden
預設隱藏所有內嵌函式,從而減小匯出符號表的大小,既能縮減檔案的大小,還能提高運行效能,我們強烈建議你在編譯任何共用庫的時候使用該選項。參見 -fvisibility=hidden 選項。
LDFLAGS

LDFLAGS 是傳遞給連接器的選項。這是一個常被忽視的變數,事實上它對最佳化的影響也是很明顯的。

-s
刪除可執行程式中的所有符號表和所有重定位資訊。其結果與運行命令 strip 所達到的效果相同,這個選項是比較安全的。
-Wl,options
options是由一個或多個逗號分隔的傳遞給連結器的選項列表。其中的每一個選項均會作為命令列選項提供給連結器。
-Wl,-On
當n>0時將會最佳化輸出,但是會明顯增加串連操作的時間,這個選項是比較安全的。
-Wl,--exclude-libs=ALL
不自動匯出庫中的符號,也就是預設將庫中的符號隱藏。
-Wl,-m<emulation>
模擬<emulation>連接器,當前ld所有可用的模擬可以通過"ld -V"命令擷取。預設值取決於ld的編譯時間配置。
-Wl,--sort-common
把全域公用符號按照大小排序後放到適當的輸出節,以防止符號間因為排布限制而出現間隙。
-Wl,-x
刪除所有的本地符號。
-Wl,-X
刪除所有的臨時本地符號。對於大多數目標平台,就是所有的名字以‘L‘開頭的本地符號。
-Wl,-zcomberloc
組合多個重定位節並重新排布它們,以便讓動態符號可以被緩衝。
-Wl,--enable-new-dtags
在ELF中建立新式的"dynamic tags",但在老式的ELF系統上無法識別。
-Wl,--as-needed
移除不必要的符號引用,僅在實際需要的時候才串連,可以產生更高效的代碼。
-Wl,--no-define-common
限制對普通符號的地址分配。該選項允許那些從共用庫中引用的普通符號只在主程式中被分配地址。這會消除在共用庫中的無用的副本的空間,同時也防止了在有多個指定了搜尋路徑的動態模組在進行運行時符號解析時引起的混亂。
-Wl,--hash-style=gnu
使用gnu風格的符號散列表格式。它的動態連結效能比傳統的sysv風格(預設)有較大提升,但是它產生的可執行程式和庫與舊的Glibc以及動態連結器不相容。

最後說兩個與最佳化無關的系統內容變數,因為會影響GCC編譯器的方式,下面兩個是咱中國人比較關心的:

LANG
指定編譯器使用的字元集,可用於建立寬字元檔案、串文字、注釋;預設為英文。[目前只支援日文"C-JIS,C-SJIS,C-EUCJP",不支援中文]
LC_ALL
指定多位元組字元的字元分類,主要用於確定字串的字元邊界以及編譯器使用何種語言發出診斷訊息;預設設定與LANG相同。中文相關的幾項:"zh_CN.GB2312 , zh_CN.GB18030 , zh_CN.GBK , zh_CN.UTF-8 , zh_TW.BIG5"。

GCC 編譯最佳化指南【轉】

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.