国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
編譯器的編譯選項解析

http://blog.csdn.net/skyflying2012/article/details/22849707

2014

 盡管將源代碼編譯為二進制文件的四個步驟由不同的程序(cpp,gcc/g ,as,ld)完成,但是事實上 cpp, as, ld 都是由 gcc/g 進行間接調(diào)用的。換句話說,控制了 gcc/g 就等于控制了所有四個步驟。從 Makefile 規(guī)則中的編譯命令可以看出,編譯工具的行為全靠 CC/CXX CPPFLAGS CFLAGS/CXXFLAGS LDFLAGS 這幾個變量在控制。當然理論上控制編譯工具行為的還應當有 AS ASFLAGS ARFLAGS 等變量,但是實踐中基本上沒有軟件包使用它們。

那么我們?nèi)绾慰刂七@些變量呢?一種簡易的做法是首先設置與這些 Makefile 變量同名的環(huán)境變量并將它們 export 為全局,然后運行 configure 腳本,大多數(shù) configure 腳本會使用這同名的環(huán)境變量代替 Makefile 中的值。但是少數(shù) configure 腳本并不這樣做(比如GCC和Binutils的腳本就不傳遞LDFLAGS),你必須手動編輯生成的 Makefile 文件,在其中尋找這些變量并修改它們的值,許多源碼包在每個子文件夾中都有 Makefile 文件,真是一件很累人的事!

CC 與 CXX

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

CPPFLAGS

這是用于預處理階段的選項。不過能夠用于此變量的選項,看不出有哪個與優(yōu)化相關(guān)。如果你實在想設一個,那就使用下面這兩個吧:

-DNDEBUG
"NDEBUG"是一個標準的 ANSI 宏,表示不進行調(diào)試編譯。
-D_FILE_OFFSET_BITS=64
大多數(shù)包使用這個來提供大文件(>2G)支持。

CFLAGS 與 CXXFLAGS

CFLAGS 表示用于 C 編譯器的選項,CXXFLAGS 表示用于 C 編譯器的選項。這兩個變量實際上涵蓋了編譯和匯編兩個步驟。大多數(shù)程序和庫在編譯時默認的優(yōu)化級別是"2"(使用"-O2";選項)并且?guī)в姓{(diào)試符號來編譯,也就是 CFLAGS="-O2 -g", CXXFLAGS=$CFLAGS 。事實上,"-O2"已經(jīng)啟用絕大多數(shù)安全的優(yōu)化選項了。另一方面,由于大部分選項可以同時用于這兩個變量,所以僅在最后講述只能用于其中一個變量的選項。[提醒]下面所列選項皆為非默認選項,你只要按需添加即可。

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

-finline-functions
允許編譯器選擇某些簡單的函數(shù)在其被調(diào)用處展開,比較安全的選項,特別是在CPU二級緩存較大時建議使用。
-funswitch-loops
將循環(huán)體中不改變值的變量移動到循環(huán)體之外。
-fgcse-after-reload
為了清除多余的溢出,在重載之后執(zhí)行一個額外的載入消除步驟。

另外:

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

調(diào)試選項:

-fprofile-arcs
在使用這一選項編譯程序并運行它以創(chuàng)建包含每個代碼塊的執(zhí)行次數(shù)的文件后,程序可以再次使用 -fbranch-probabilities 編譯,文件中的信息可以用來優(yōu)化那些經(jīng)常選取的分支。如果沒有這些信息,gcc將猜測哪個分支將被經(jīng)常運行以進行優(yōu)化。這類優(yōu)化信息將會存放在一個以源文件為名字的并以".da";為后綴的文件中。

全局選項:

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

目錄選項:

--sysroot=dir
將dir作為邏輯根目錄。比如編譯器通常會在 /usr/include 和 /usr/lib 中搜索頭文件和庫,使用這個選項后將在 dir/usr/include 和 dir/usr/lib 目錄中搜索。如果使用這個選項的同時又使用了 -isysroot 選項,則此選項僅作用于庫文件的搜索路徑,而 -isysroot 選項將作用于頭文件的搜索路徑。這個選項與優(yōu)化無關(guān),但是在 CLFS 中有著神奇的作用。

代碼生成選項:

-fno-bounds-check
關(guān)閉所有對數(shù)組訪問的邊界檢查。該選項將提高數(shù)組索引的性能,但當超出數(shù)組邊界時,可能會造成不可接受的行為。
-freg-struct-return
如果struct和union足夠小就通過寄存器返回,這將提高較小結(jié)構(gòu)的效率。如果不夠小,無法容納在一個寄存器中,將使用內(nèi)存返回。建議僅在完全使用GCC編譯的系統(tǒng)上才使用。
-fpic
生成可用于共享庫的位置獨立代碼。所有的內(nèi)部尋址均通過全局偏移表完成。要確定一個地址,需要將代碼自身的內(nèi)存位置作為表中一項插入。該選項產(chǎn)生可以在共享庫中存放并從中加載的目標模塊。
-fstack-check
為防止程序棧溢出而進行必要的檢測,僅在多線程環(huán)境中運行時才可能需要它。
-fvisibility=hidden
設置默認的ELF鏡像中符號的可見性為隱藏。使用這個特性可以非常充分的提高連接和加載共享庫的性能,生成更加優(yōu)化的代碼,提供近乎完美的API輸出和防止符號碰撞。我們強烈建議你在編譯任何共享庫的時候使用該選項。參見 -fvisibility-inlines-hidden 選項。

硬件體系結(jié)構(gòu)相關(guān)選項[僅僅針對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對齊于雙字節(jié)邊界上;有助于生成更高速的代碼,但是程序的尺寸會變大,并且不能與未使用該選項編譯的程序一起工作。
-m128bit-long-double
指定long double為128位,pentium以上的cpu更喜歡這種標準,并且符合x86-64的ABI標準,但是卻不附合i386的ABI標準。
-mregparm=N
指定用于傳遞整數(shù)參數(shù)的寄存器數(shù)目(默認不使用寄存器)。0<=N<=3 ;注意:當N>0時你必須使用同一參數(shù)重新構(gòu)建所有的模塊,包括所有的庫。
-msseregparm
使用SSE寄存器傳遞float和double參數(shù)和返回值。注意:當你使用了這個選項以后,你必須使用同一參數(shù)重新構(gòu)建所有的模塊,包括所有的庫。-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新增)
是否使用相應的擴展指令集以及內(nèi)置函數(shù),按照自己的cpu選擇吧!
-maccumulate-outgoing-args
指定在函數(shù)引導段中計算輸出參數(shù)所需最大空間,這在大部分現(xiàn)代cpu中是較快的方法;缺點是會明顯增加二進制文件尺寸。
-mthreads
支持Mingw32的線程安全異常處理。對于依賴于線程安全異常處理的程序,必須啟用這個選項。使用這個選項時會定義"-D_MT",它將包含使用選項"-lmingwthrd"連接的一個特殊的線程輔助庫,用于為每個線程清理異常處理數(shù)據(jù)。
-minline-all-stringops
默認時GCC只將確定目的地會被對齊在至少4字節(jié)邊界的字符串操作內(nèi)聯(lián)進程序代碼。該選項啟用更多的內(nèi)聯(lián)并且增加二進制文件的體積,但是可以提升依賴于高速 memcpy, strlen, memset 操作的程序的性能。
-minline-stringops-dynamically
GCC-4.3新增。對未知尺寸字符串的小塊操作使用內(nèi)聯(lián)代碼,而對大塊操作仍然調(diào)用庫函數(shù),這是比"-minline-all-stringops"更聰明的策略。決定策略的算法可以通過"-mstringop-strategy"控制。
-momit-leaf-frame-pointer
不為葉子函數(shù)在寄存器中保存棧指針,這樣可以節(jié)省寄存器,但是將會使調(diào)試變的困難。注意:不要與 -fomit-frame-pointer 同時使用,因為會造成代碼效率低下。
-m64
生成專門運行于64位環(huán)境的代碼,不能運行于32位環(huán)境,僅用于x86_64[含EMT64]環(huán)境。
-mcmodel=small
[默認值]程序和它的符號必須位于2GB以下的地址空間。指針仍然是64位。程序可以靜態(tài)連接也可以動態(tài)連接。僅用于x86_64[含EMT64]環(huán)境。
-mcmodel=kernel
內(nèi)核運行于2GB地址空間之外。在編譯linux內(nèi)核時必須使用該選項!僅用于x86_64[含EMT64]環(huán)境。
-mcmodel=medium
程序必須位于2GB以下的地址空間,但是它的符號可以位于任何地址空間。程序可以靜態(tài)連接也可以動態(tài)連接。注意:共享庫不能使用這個選項編譯!僅用于x86_64[含EMT64]環(huán)境。

其它優(yōu)化選項:

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

傳遞給匯編器的選項:

-Wa,options
options是一個或多個由逗號分隔的可以傳遞給匯編器的選項列表。其中的每一個均可作為命令行選項傳遞給匯編器。
-Wa,--strip-local-absolute
從輸出符號表中移除局部絕對符號。
-Wa,-R
合并數(shù)據(jù)段和正文段,因為不必在數(shù)據(jù)段和代碼段之間轉(zhuǎn)移,所以它可能會產(chǎn)生更短的地址移動。
-Wa,--64
設置字長為64bit,僅用于x86_64,并且僅對ELF格式的目標文件有效。此外,還需要使用"--enable-64-bit-bfd"選項編譯的BFD支持。
-Wa,-march=CPU
按照特定的CPU進行優(yōu)化:pentiumiii, pentium4, prescott, nocona, core, core2; athlon, sledgehammer, opteron, k8 。

僅可用于 CFLAGS 的選項:

-fhosted
按宿主環(huán)境編譯,其中需要有完整的標準庫,入口必須是main()函數(shù)且具有int型的返回值。內(nèi)核以外幾乎所有的程序都是如此。該選項隱含設置了 -fbuiltin,且與 -fno-freestanding 等價。
-ffreestanding
按獨立環(huán)境編譯,該環(huán)境可以沒有標準庫,且對main()函數(shù)沒有要求。最典型的例子就是操作系統(tǒng)內(nèi)核。該選項隱含設置了 -fno-builtin,且與 -fno-hosted 等價。

僅可用于 CXXFLAGS 的選項:

-fno-enforce-eh-specs
C 標準要求強制檢查異常違例,但是該選項可以關(guān)閉違例檢查,從而減小生成代碼的體積。該選項類似于定義了";NDEBUG"宏。
-fno-rtti
如果沒有使用'dynamic_cast'和'typeid',可以使用這個選項禁止為包含虛方法的類生成運行時表示代碼,從而節(jié)約空間。此選項對于異常處理無效(仍然按需生成rtti代碼)。
-ftemplate-depth-n
將最大模版實例化深度設為'n',符合標準的程序不能超過17,默認值為500。
-fno-optional-diags
禁止輸出診斷消息,C 標準并不需要這些消息。
-fno-threadsafe-statics
GCC自動在訪問C 局部靜態(tài)變量的代碼上加鎖,以保證線程安全。如果你不需要線程安全,可以使用這個選項。
-fvisibility-inlines-hidden
默認隱藏所有內(nèi)聯(lián)函數(shù),從而減小導出符號表的大小,既能縮減文件的大小,還能提高運行性能,我們強烈建議你在編譯任何共享庫的時候使用該選項。參見 -fvisibility=hidden 選項。

LDFLAGS

LDFLAGS 是傳遞給連接器的選項。這是一個常被忽視的變量,事實上它對優(yōu)化的影響也是很明顯的。

-s
刪除可執(zhí)行程序中的所有符號表和所有重定位信息。其結(jié)果與運行命令 strip 所達到的效果相同,這個選項是比較安全的。
-Wl,options
options是由一個或多個逗號分隔的傳遞給鏈接器的選項列表。其中的每一個選項均會作為命令行選項提供給鏈接器。
-Wl,-On
當n>0時將會優(yōu)化輸出,但是會明顯增加連接操作的時間,這個選項是比較安全的。
-Wl,--exclude-libs=ALL
不自動導出庫中的符號,也就是默認將庫中的符號隱藏。
-Wl,-m<emulation>
仿真<emulation>連接器,當前l(fā)d所有可用的仿真可以通過"ld -V"命令獲取。默認值取決于ld的編譯時配置。
-Wl,--sort-common
把全局公共符號按照大小排序后放到適當?shù)妮敵龉?jié),以防止符號間因為排布限制而出現(xiàn)間隙。
-Wl,-x
刪除所有的本地符號。
-Wl,-X
刪除所有的臨時本地符號。對于大多數(shù)目標平臺,就是所有的名字以'L'開頭的本地符號。
-Wl,-zcomberloc
組合多個重定位節(jié)并重新排布它們,以便讓動態(tài)符號可以被緩存。
-Wl,--enable-new-dtags
在ELF中創(chuàng)建新式的"dynamic tags",但在老式的ELF系統(tǒng)上無法識別。
-Wl,--as-needed
移除不必要的符號引用,僅在實際需要的時候才連接,可以生成更高效的代碼。
-Wl,--no-define-common
限制對普通符號的地址分配。該選項允許那些從共享庫中引用的普通符號只在主程序中被分配地址。這會消除在共享庫中的無用的副本的空間,同時也防止了在有多個指定了搜索路徑的動態(tài)模塊在進行運行時符號解析時引起的混亂。
-Wl,--hash-style=gnu
使用gnu風格的符號散列表格式。它的動態(tài)鏈接性能比傳統(tǒng)的sysv風格(默認)有較大提升,但是它生成的可執(zhí)行程序和庫與舊的Glibc以及動態(tài)鏈接器不兼容。

最后說兩個與優(yōu)化無關(guān)的系統(tǒng)環(huán)境變量,因為會影響GCC編譯程序的方式,下面兩個是咱中國人比較關(guān)心的:

LANG
指定編譯程序使用的字符集,可用于創(chuàng)建寬字符文件、串文字、注釋;默認為英文。[目前只支持日文"C-JIS,C-SJIS,C-EUCJP",不支持中文]
LC_ALL
指定多字節(jié)字符的字符分類,主要用于確定字符串的字符邊界以及編譯程序使用何種語言發(fā)出診斷消息;默認設置與LANG相同。中文相關(guān)的幾項:"zh_CN.GB2312 , zh_CN.GB18030 , zh_CN.GBK , zh_CN.UTF-8 , zh_TW.BIG5"。
本站僅提供存儲服務,所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
GCC編譯優(yōu)化指南
[原創(chuàng)]GCC編譯器選項及優(yōu)化提示
Using GCC’s C++ Compiler
再理解編譯鏈接過程(GCC編譯器)
gcc編譯器使用入門--溪流百里涼
如何利用GCC編譯選項檢測棧溢出
更多類似文章 >>
生活服務
分享 收藏 導長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服