GCC编译优化选项

2019-01-03 19:52:55 浏览数 (1)

GCC编译优化选项

参考GCC文档 http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html.

查看GCC各选项打开的优化项:gcc -Q --help=optimizers。分为如下:

代码语言:txt复制
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普遍比较谨慎,主要因为:

  1. 前期Gcc版本中,O3 is buggy
  2. O3往往优化后比O2还要慢一些

第2点,主要是因为,O3在做优化时,采用了很激进的策略,例如激进的循环展开、函数内联等,导致生成的代码比较大,可能超出了CPU的指令Cacheinstruction cache,破坏了局部性和完整性。

对C 开发而言,性能提升最明显的大概还是:

  1. 对齐allignment,变量内存和指令 -falign
  2. stl的优化
    1. 小函数内联优化 -finline-small-functions
    2. template未调用的函数不会被编译
    3. template独立编译每个类型

template增加编译时间,但往往性能会有更好的提升。主要在于,template的机制使得更多的小函数内联成为可能。以std::sort为例,和C的qsort对比,参考stack flow上这个问题C templates for performance? 。

gcc

0 人点赞