-O1 -O2 -O3 優化的原理是什麽?
阿新 • • 發佈:2018-07-14
-o3 ria moni text 獲取 目的 時間 代碼 設置
1.-O,-O1:
這兩個命令的效果是一樣的,目的都是在不影響編譯速度的前提下,盡量采用一些優化算法降低代碼大小和可執行代碼的運行速度。並開啟如下的優化選項:
該優化選項會犧牲部分編譯速度,除了執行-O1所執行的所有優化之外,還會采用幾乎所有的目標配置支持的優化算法,用以提高目標代碼的運行速度。
3. -O3
該選項除了執行-O2所有的優化選項之外,一般都是采取很多向量化算法,提高代碼的並行執行程度,利用現代CPU中的流水線,Cache等。
這個優化標識和-O3有異曲同工之妙,當然兩者的目標不一樣,-O3的目標是寧願增加目標代碼的大小,也要拼命的提高運行速度,但是這個選項是在-O2的基礎之上,盡量的降低目標代碼的大小,這對於存儲容量很小的設備來說非常重要。
為了降低目標代碼大小,會禁用下列優化選項,一般就是壓縮內存中的對齊空白(alignment padding)
該選項將不會嚴格遵循語言標準,除了啟用所有的-O3優化選項之外,也會針對某些語言啟用部分優化。如:-ffast-math ,對於Fortran語言,還會啟用下列選項:
該標識會精心挑選部分與-g選項不沖突的優化選項,當然就能提供合理的優化水平,同時產生較好的可調試信息和對語言標準的遵循程度。 (部分轉自:知乎)
一般來說,如果不指定優化標識的話,gcc就會產生可調試代碼,每條指令之間將是獨立的:可以在指令之間設置斷點,使用gdb中的 p命令查看變量的值,改變變量的值等。並且把獲取最快的編譯速度作為它的目標。
當優化標識被啟用之後,gcc編譯器將會試圖改變程序的結構(當然會在保證變換之後的程序與源程序語義等價的前提之下),以滿足某些目標,如:代碼大小最小或運行速度更快(只不過通常來說,這兩個目標是矛盾的,二者不可兼得)。
在不同的gcc配置和目標平臺下,同一個標識所采用的優化種類也是不一樣的,這可以使用-Q --help =optimizers來獲取每個優化標識所啟用的優化選項。
下面每個-f**優化標識都可以在上述鏈接中找到解釋
1.-O,-O1:
這兩個命令的效果是一樣的,目的都是在不影響編譯速度的前提下,盡量采用一些優化算法降低代碼大小和可執行代碼的運行速度。並開啟如下的優化選項:
2. -O2-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
該優化選項會犧牲部分編譯速度,除了執行-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選項不沖突的優化選項,當然就能提供合理的優化水平,同時產生較好的可調試信息和對語言標準的遵循程度。 (部分轉自:知乎)
-O1 -O2 -O3 優化的原理是什麽?