gcc 中-O -O1 -O2 -O3 -Os -Ofast -Og優化的原理

一般來說,如果不指定優化標識的話,gcc就會產生可調試代碼,每條指令之間將是獨立的:可以在指令之間設置斷點,使用gdb中的 p命令查看變量的值,改變變量的值等。並且把獲取最快的編譯速度作爲它的目標。

       當優化標識被啓用之後,gcc編譯器將會試圖改變程序的結構(當然會在保證變換之後的程序與源程序語義等價的前提之下),以滿足某些目標,如:代碼大小最小或運行速度更快(只不過通常來說,這兩個目標是矛盾的,二者不可兼得)。

       在不同的gcc配置和目標平臺下,同一個標識所採用的優化種類也是不一樣的,這可以使用-Q --help =optimizers來獲取每個優化標識所啓用的優化選項。

下面每個-f**優化標識都可以在上述鏈接中找到解釋


1.-O,-O1:


       這兩個命令的效果是一樣的,目的都是在不影響編譯速度的前提下,儘量採用一些優化算法降低代碼大小和可執行代碼的運行速度。並開啓如下的優化選項:


-fauto-inc-dec

-fbranch-count-reg

-fcombine-stack-adjustments

-fcompare-elim

-fcprop-registers

-fdce

-fdefer-pop

-fdelayed-branch

-fdse

-fforward-propagate

-fguess-branch-probability

-fif-conversion2

-fif-conversion

-finline-functions-called-once

-fipa-pure-const

-fipa-profile

-fipa-reference

-fmerge-constants

-fmove-loop-invariants

-freorder-blocks

-fshrink-wrap

-fshrink-wrap-separate

-fsplit-wide-types

-fssa-backprop

-fssa-phiopt

-fstore-merging

-ftree-bit-ccp

-ftree-ccp

-ftree-ch

-ftree-coalesce-vars

-ftree-copy-prop

-ftree-dce

-ftree-dominator-opts

-ftree-dse

-ftree-forwprop

-ftree-fre

-ftree-phiprop

-ftree-sink

-ftree-slsr

-ftree-sra

-ftree-pta

-ftree-ter

-funit-at-a-time

 


2. -O2


       該優化選項會犧牲部分編譯速度,除了執行-O1所執行的所有優化之外,還會採用幾乎所有的目標配置支持的優化算法,用以提高目標代碼的運行速度。


-fthread-jumps

-falign-functions  -falign-jumps

-falign-loops  -falign-labels

-fcaller-saves

-fcrossjumping

-fcse-follow-jumps  -fcse-skip-blocks

-fdelete-null-pointer-checks

-fdevirtualize -fdevirtualize-speculatively

-fexpensive-optimizations

-fgcse  -fgcse-lm 

-fhoist-adjacent-loads

-finline-small-functions

-findirect-inlining

-fipa-cp

-fipa-cp-alignment

-fipa-bit-cp

-fipa-sra

-fipa-icf

-fisolate-erroneous-paths-dereference

-flra-remat

-foptimize-sibling-calls

-foptimize-strlen

-fpartial-inlining

-fpeephole2

-freorder-blocks-algorithm=stc

-freorder-blocks-and-partition -freorder-functions

-frerun-cse-after-loop 

-fsched-interblock  -fsched-spec

-fschedule-insns  -fschedule-insns2

-fstrict-aliasing -fstrict-overflow

-ftree-builtin-call-dce

-ftree-switch-conversion -ftree-tail-merge

-fcode-hoisting

-ftree-pre

-ftree-vrp

-fipa-ra


3. -O3


       該選項除了執行-O2所有的優化選項之外,一般都是採取很多向量化算法,提高代碼的並行執行程度,利用現代CPU中的流水線,Cache等。


-finline-functions      // 採用一些啓發式算法對函數進行內聯

-funswitch-loops        // 執行循環unswitch變換

-fpredictive-commoning  //

-fgcse-after-reload     //執行全局的共同子表達式消除

-ftree-loop-vectorize   //

-ftree-loop-distribute-patterns

-fsplit-paths

-ftree-slp-vectorize

-fvect-cost-model

-ftree-partial-pre

-fpeel-loops

-fipa-cp-clone options

這個選項會提高執行代碼的大小,當然會降低目標代碼的執行時間。


4. -Os


       這個優化標識和-O3有異曲同工之妙,當然兩者的目標不一樣,-O3的目標是寧願增加目標代碼的大小,也要拼命的提高運行速度,但是這個選項是在-O2的基礎之上,儘量的降低目標代碼的大小,這對於存儲容量很小的設備來說非常重要。
爲了降低目標代碼大小,會禁用下列優化選項,一般就是壓縮內存中的對齊空白(alignment padding)


-falign-functions 

-falign-jumps 

-falign-loops

-falign-labels

-freorder-blocks 

-freorder-blocks-algorithm=stc

-freorder-blocks-and-partition 

-fprefetch-loop-arrays


5. -Ofast:


      該選項將不會嚴格遵循語言標準,除了啓用所有的-O3優化選項之外,也會針對某些語言啓用部分優化。如:-ffast-math ,對於Fortran語言,還會啓用下列選項:

-fno-protect-parens

-fstack-arrays

6.-Og:


      該標識會精心挑選部分與-g選項不衝突的優化選項,當然就能提供合理的優化水平,同時產生較好的可調試信息和對語言標準的遵循程度。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章