1 GCC/G++中的编译优化选项

gcc/g++编译程序时,不同优化编译选项,如-O1-O2-O3等会产生不同的程序大小以及程序运行速度。本文将对GCC/G++中的不同编译选项进行简要的介绍。

1.1 -O0

如果GCC不指定编译优化选项,那么会设置为-O0。

-O0主要可以减少代码编译时间并保留调试信息。

1.2 -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-conversion 
-fif-conversion2 
-finline-functions-called-once 
-fipa-modref 
-fipa-profile 
-fipa-pure-const 
-fipa-reference 
-fipa-reference-addressable 
-fmerge-constants 
-fmove-loop-invariants 
-fmove-loop-stores
-fomit-frame-pointer 
-freorder-blocks 
-fshrink-wrap 
-fshrink-wrap-separate 
-fsplit-wide-types 
-fssa-backprop 
-fssa-phiopt 
-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-pta 
-ftree-scev-cprop 
-ftree-sink 
-ftree-slsr 
-ftree-sra 
-ftree-ter 
-funit-at-a-time

1.3 -O2

-O2选项将在-O1的基础上进一步优化,不过与-O1相比,会增加编译时间(牺牲编译速度)以及进一步降低代码运行时间。-O2选项除了开启-O1的所有优化标志外,还会开启以下优化标志:

-falign-functions  -falign-jumps 
-falign-labels  -falign-loops 
-fcaller-saves 
-fcode-hoisting 
-fcrossjumping 
-fcse-follow-jumps  -fcse-skip-blocks 
-fdelete-null-pointer-checks 
-fdevirtualize  -fdevirtualize-speculatively 
-fexpensive-optimizations 
-ffinite-loops 
-fgcse  -fgcse-lm  
-fhoist-adjacent-loads 
-finline-functions 
-finline-small-functions 
-findirect-inlining 
-fipa-bit-cp  -fipa-cp  -fipa-icf 
-fipa-ra  -fipa-sra  -fipa-vrp 
-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  
-fschedule-insns  -fschedule-insns2 
-fsched-interblock  -fsched-spec 
-fstore-merging 
-fstrict-aliasing 
-fthread-jumps 
-ftree-builtin-call-dce 
-ftree-loop-vectorize 
-ftree-pre 
-ftree-slp-vectorize 
-ftree-switch-conversion  -ftree-tail-merge 
-ftree-vrp 
-fvect-cost-model=very-cheap

1.4 -O3

与-O2相比,进一步优化,一般都是采取很多向量化算法,提高代码的并行执行程度,利用现代CPU中的流水线,Cache等。

-O3除了开启-O2的所有优化标志外,还会开启以下优化标志:

-fgcse-after-reload 
-fipa-cp-clone 
-floop-interchange 
-floop-unroll-and-jam 
-fpeel-loops 
-fpredictive- 
commoning -fsplit-loops 
-fsplit-paths 
-ftree-loop-distribution 
-ftree-partial -pre 
-funswitch-loops 
-fvect-cost-model=dynamic 
-fversion-loops-for-strides

1.5 -Os

-Os与-O2的优化标志差不多,但是不包括-O2中增加代码大小的优化标志:

-falign-functions -falign-jumps 
-falign-labels -falign-loops 
-fprefetch-loop-arrays -freorder-blocks-algorithm=stc

-Os与-O2相比,主要在于优化代码大小。-Os使用-finline函数,使编译器调整代码大小而不是调整运行速度。

1.6 -Ofast

该选项将不会严格遵循语言标准,除了启用所有的-O3优化选项之外,也会针对某些语言启用部分优化。如:-ffast-math ,-fallow-store-data-races,和特定于Fortan语言的-fstack-arrays标志,除非 -fmax-stack-var-size和-fno-protect-parens被指定。-Ofast主要是牺牲兼容性来获取更快的运行速度。

1.7 -Og

-Og主要是在快速编译与可调试之间保持一个合理的优化策略。-Og延用了-O1中的优化标志,但是不包括-O1中对调试信息产生影响的标志,比如说:

-fbranch-count-reg -fdelayed-branch 
-fdse -fif-conversion -fif-conversion2   
-finline-functions-called-once 
-fmove-loop-invariants -fmove-loop-stores -fssa-phiopt 
-ftree-bit-ccp -ftree-dse -ftree-pta -ftree-sra

1.8 -Oz

-Oz主要在于优化程序代码大小而不是优化代码运行速度,对于可执行程序大小及其敏感的业务可以使用此种优化选项。-Oz与-O2的大部分优化标志类似。

1.9 需要注意的点

如果在gcc编译中指定了多个-Oxxx级别的优化标志,起作用的一般是最后一个优化标志。

参考链接