公告:

诚信为本:市场永远在变,诚信永远不变。

7x24小时咨询热线:0898-88889999
速盈资讯

当前位置: 首页 > 速盈资讯

GCC中-O1 -O2 -O3 优化的原理是什么?

发布时间:2024-08-26 06:07:33 浏览次数:

做OI时候发现C++开了O2优化后可以在不超时的情况下随便用STL,非常好奇这是怎么实现的?

俺来打个酱油。后面有谁来展开解答这个话题就功德无量了。

@vczh

大大讲了C++的语言和STL的一侧。这只覆盖了要优化的对象但没覆盖如何优化。

@空明流转

大大讲了编译器优化话题太巨大。话题是巨大,不过总有切入点。

楼主只是想大概知道些名词但不想太深入的话,可以先从GCC的文档入手:

gcc.gnu.org/onlinedocs/

这份文档讲解了每层-O参数对应哪些具体的优化。每个具体的优化参数是“-f + 优化名”,例如-fdce的优化名是DCE,也就是dead code elimination。

知道优化的名字就可以去搜搜相关资料了。唯一的问题就是GCC用的这些优化名称可能跟教科书叫法不一样? 例如-fmove-loop-invariant在其它资料里可能更多叫做loop-invariant code motion(LICM)。

更高层一点,还可以从文档中了解一下GCC的工作流程:

gcc.gnu.org/onlinedocs/

-On(n=0,1,2,3,也可以是其它单词)是gcc为了一般人方便而做的设定,根据n值大小包含预设标准由低到高的一些优化选项,均为-fxxx(xxx为优化项),但注意,即使是最高优化选项-O3,也不是包含所有的-f选项,这只是为大多数人的使用方便而预设的。

-O0: This level (that is the letter "O" followed by a zero) turns off optimization entirely and is the default if no -O level is specified in CFLAGS or CXXFLAGS. This reduces compilation time and can improve debugging info, but some applications will not work properly without optimization enabled. This option is not recommended except for debugging purposes.

-O1: the most basic optimization level. The compiler will try to produce faster, smaller code without taking much compilation time. It is basic, but it should get the job done all the time.

-O2: A step up from -O1. The recommended level of optimization unless the system has special needs. -O2 will activate a few more flags in addition to the ones activated by -O1. With -O2, the compiler will attempt to increase code performance without compromising on size, and without taking too much compilation time.

-O3: the highest level of optimization possible. It enables optimizations that are expensive in terms of compile time and memory usage. Compiling with -O3 is not a guaranteed way to improve performance, and in fact, in many cases, can slow down a system due to larger binaries and increased memory usage. -O3 is also known to break several packages. Using -O3 is not recommended.

-Os: optimizes code for size. It activates all -O2 options that do not increase the size of the generated code. It can be useful for machines that have extremely limited disk storage space and/or CPUs with small cache sizes.

-Og: In GCC 4.8, a new general optimization level, -Og, has been introduced. It addresses the need for fast compilation and a superior debugging experience while providing a reasonable level of runtime performance. Overall experience for development should be better than the default optimization level -O0. Note that -Og does not imply -g, it simply disables optimizations that may interfere with debugging.

-Ofast: New in GCC 4.7, consists of -O3 plus -ffast-math, -fno-protect-parens, and -fstack-arrays. This option breaks strict standards compliance, and is not recommended for use.

你开了-O2,stl里大量的函数都被inline了,故而比原来快好多,毋庸置疑,stl没有inline基本上是威力全无,切记。

虽然-O3的建议程度不比-O2,但个人推荐-O3作为release版本的选项,因为它开启了重要的-finline-functions,对于实在是要在乎code size的情况,配合使用noinline。这总比费劲心思profiling然后写inline函数来得简单。

不不,你完全理解反了。开着-O2、-O3才是人家期望你用来生产最终产品的用法,无优化是给你调试用的。C++标准容器本来就应当是(在开启优化的时候)几乎不产生额外代价的。

一下内容摘自

Using the GNU Compiler Collection (GCC)

一般来说,如果不指定优化标识的话,gcc就会产生可调试代码,每条指令之间将是独立的:可以在指令之间设置断点,使用gdb中的 p命令查看变量的值,改变变量的值等。并且把获取最快的编译速度作为它的目标。

当优化标识被启用之后,gcc编译器将会试图改变程序的结构(当然会在保证变换之后的程序与源程序语义等价的前提之下),以满足某些目标,如:代码大小最小或运行速度更快(只不过通常来说,这两个目标是矛盾的,二者不可兼得)。

在不同的gcc配置和目标平台下,同一个标识所采用的优化种类也是不一样的,这可以使用-Q --help=optimizers来获取每个优化标识所启用的优化选项。

下面每个-f**优化标识都可以在上述链接中找到解释


1.-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-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

2. -O2

该优化选项会牺牲部分编译速度,除了执行-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选项不冲突的优化选项,当然就能提供合理的优化水平,同时产生较好的可调试信息和对语言标准的遵循程度。

我只知道gcc -O4 优化

把代码发给Jeff Dean重写

地址:海南省海口市58号 电话:0898-88889999 手机:13988888888

Copyright © 2012-2018 首页-速盈娱乐-注册登录站 ICP备案编号:琼ICP备88889999号