在使用编译程序的时候,如果不启动优化选项,gcc会产生有利于调试的编译结果,例如使用gdb可以方便查看、修改源代码中的变量的值;如果启用优化选项,gcc会使用更多的编译时间和牺牲程序的可调试性为代价来提高程序的性能或者减少代码大小。
在不同的gcc版本和目标平台下,同一个优化选项所启动的优化标识集合也不一样,可以使用-Q --help=optimizers
来获取相应的优化选项采用的优化标识集。在下文中的每个-f**
优化标识都可以在参考链接中查询到具体的含义。
在编译源码+调试的过程中,使用到比较多的是-O0
和-Og
两个优化选项。-O0
不会启动任何优化标识,能产生有利于调试的可执行程序,但是有些时候在编译大型程序(例如我在编译libc)的时候,使用该选项会报错;-Og
则是进行合理优化的程度上保证了程序的可调试性。
-O0
减少编译时间,产生方便调试的程序,是gcc的默认设置
-Og
优化调试体验。提供合理的优化级别,同时保证快速编译和良好的调试体验。有时候修改Makefile到-O0会失败,这是因为编译器在收集调试信息的时候会禁用-O0,这个时候就可以使用-Og。
-O、-O1
-O、- O1:二者是一样的,都是在不影响编译速度的前提下,采用一些优化算法来减少代码的大小和提高代码的运行速度,开启的优化选项如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| -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
|
-O2
在-O的基础上优化更多的选项,会增加编译时间、提高代码的性能。新增加的优化选项如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| -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
|
-O3
在-O2的优化选项基础上,采用了更多的向量化算法,利用现代CPU中的流水线、cache等特性提高代码的并行执行速度。该选项会增加代码大小。
1 2 3 4 5 6 7 8 9 10 11 12 13
| -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
|
-Os
这个编译选项和-O3相反,-O3是牺牲代码的空间换取执行时间,-O4则是牺牲代码的执行时间降低代码大小,这在一些存储容量较少的设备中非常重要,例如嵌入式设备。
-Os也是在-O2的基础上,使用了如下的优化选项,通过优化选项可以看出是对代码的空白对齐进行了压缩之类的操作。
1 2 3 4 5 6
| -falign-functions -falign-jumps -falign-labels -falign-loops -fprefetch-loop-arrays -freorder-blocks-algorithm=stc
|
-Ofast
在-O3的优化选项基础上,无视严格的标准合规性(不是很懂什么意思)
参考链接