GCC编译优化选项
参考GCC文档 http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html.
查看GCC各选项打开的优化项:gcc -Q --help=optimizers
。分为如下:
O0: 默认选项,目的: 减少编译时间;生成可调试代码(可打断)
O/O1: 做一些不显著增加编译时间的优化
O2: 显著提升编译时间,提升代码性能,做不包含`space-speed tradeoff`的所有优化
O3: 进一步优化,显著增加可执行文件大小。
Os: 优化性能同时不增加可执行文件大小。包含O2选项中不增加代码大小的优化项
Og: 优化性能同时不损害可调试性。包含O1选项中不损害可调试性的优化项
Ofast: 忽视严格的标准编译性。包含O3中所有选项及` -ffast-math`
O1优化项
代码语言:txt复制-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-profile
-fipa-pure-const
-fipa-reference
-fipa-reference-addressable
-fmerge-constants
-fmove-loop-invariants
-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优化项
O1基础上叠加如下项。
代码语言:txt复制-falign-functions -falign-jumps ---- 对齐函数地址,加快CPU访问速度,增加代码大小
-falign-labels -falign-loops ---- 同上
-fcaller-saves
-fcode-hoisting
-fcrossjumping ---- 生成一致代码,减少代码大小
-fcse-follow-jumps ----
-fdelete-null-pointer-checks ---- 去除无用空指针检查(解引用后的检查)
-fdevirtualize -fdevirtualize-speculatively ---- 尝试优化虚函数调用为实际函数调用,猜测实际调用的对象
-fexpensive-optimizations ---- 一些很耗费CPU的次要优化
-fgcse -fgcse-lm ---- 尝试进行公同子串表达式替换 common subexpress elimination
-fhoist-adjacent-loads ---- likely和unlikely 猜测if/else的情况
-finline-small-functions ---- 小函数inline化
-findirect-inlining ---- 对不是直接调用的小函数也尝试做inline,基于上面的推测
-fipa-bit-cp -fipa-cp -fipa-icf
-fipa-ra -fipa-sra -fipa-vrp
-fisolate-erroneous-paths-dereference ---- 检测可能导致空指针解引用的异常逻辑,并和主逻辑隔离
-flra-remat
-foptimize-sibling-calls ---- 优化重复调用和递归调用
-foptimize-strlen ---- 优化标准C strlen函数实现
-fpartial-inlining ---- 内联函数的某些部分
-fpeephole2 ---- 特定机型的优化
-freorder-blocks-algorithm=stc ---- 代码块重新排序,software trace cache算法,把常调用的部分流程聚合在一起
-freorder-blocks-and-partition -freorder-functions ---- 根据局部性原理,将常调用的代码块放在同一个.o文件中
-frerun-cse-after-loop ---- loop优化后重新执行csc
-fschedule-insns -fschedule-insns2 ---- 优化代码执行次序(减少CPU等待获取数据的损耗)
-fsched-interblock -fsched-spec
-fstore-merging ---- 及时数对齐,不足1个Word的填充为1个Word
-fstrict-aliasing
-fthread-jumps ---- 对代码跳转路径的优化
-ftree-builtin-call-dce ---- 去除不可达代码
-ftree-pre ---- 执行partial redundancy elimination
-ftree-switch-conversion -ftree-tail-merge ---- 对switch的优化
-ftree-vrp ---- 剔除无用变量范围检查
O3优化项
使用一些向量型算法,提高代码并行执行程度,利用现代CPU中的流水线、Cache等。
O2基础上叠加如下项。
代码语言:txt复制-fgcse-after-reload
-finline-functions
-fipa-cp-clone
-floop-interchange
-floop-unroll-and-jam
-fpeel-loops
-fpredictive-commoning
-fsplit-paths
-ftree-loop-distribute-patterns
-ftree-loop-distribution
-ftree-loop-vectorize
-ftree-partial-pre
-ftree-slp-vectorize
-funswitch-loops
-fvect-cost-model
-fversion-loops-for-strides
大家对O3普遍比较谨慎,主要因为:
- 前期Gcc版本中,O3 is buggy
- O3往往优化后比O2还要慢一些
第2点,主要是因为,O3在做优化时,采用了很激进的策略,例如激进的循环展开、函数内联等,导致生成的代码比较大,可能超出了CPU的指令Cacheinstruction cache
,破坏了局部性和完整性。
对C 开发而言,性能提升最明显的大概还是:
- 对齐allignment,变量内存和指令
-falign
- stl的优化
- 小函数内联优化
-finline-small-functions
- template未调用的函数不会被编译
- template独立编译每个类型
- 小函数内联优化
template增加编译时间,但往往性能会有更好的提升。主要在于,template的机制使得更多的小函数内联成为可能。以std::sort为例,和C的qsort对比,参考stack flow上这个问题C templates for performance? 。