gcc -O0 -O1 -O2 -O3 -Os 编译优化等级
Posted Li-Yongjun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了gcc -O0 -O1 -O2 -O3 -Os 编译优化等级相关的知识,希望对你有一定的参考价值。
优化等级
gcc 提供了大量优化等级,用来对编译时间、目标文件大小、执行效率三个维度进行不同的取舍和平衡
-O0
,最少的优化。(这是默认的编译选项)(可以最大程度上配合产生代码调试信息,可以在任何代码行打断点,特别是死代码处)-O
或-O1
,有限优化。(编译时占用稍微多的时间和相当大的内存,减少代码生成尺寸、缩短执行时间)(去除无用的 inline 和无用的 static 函数、死代码消除等,在影响到调试信息的地方均不进行优化,在适当的代码体积和充分的调试之间平衡,代码编写阶段最常用的优化等级)-O2
,高度优化。(在 -O1 的基础上,尝试更多的寄存器级的优化以及指令级的优化)(调试信息不友好,有可能会修改代码和函数调用执行流程,自动对函数进行内联)-O3
,最大程度优化。(在 -O2 的基础上,针对循环进行更多的优化,更激进的函数内陆等)-Os
,相当于 -O2.5。使用了所有 -O2 的优化选项,但又不缩减代码尺寸的方法。
实战演练
使用 STM32CubeMX 新建一个简单 demo,并用 Keil5 打开,使用 STM32CubeMX 创建的工程,gcc 编译优化等级默认为 -O3。
在 main() 函数里有一句 int a = 100;
,打开仿真,发现这句被编译成的汇编语句为
MOVS r0,#0x64
即,将 r0 寄存器赋值为 100,就没有然后了。
我们手动将优化等级改为 -O0,重新看 int a = 100;
对应的汇编语句,发现是两句
MOVS r0,#0x64
STR r0,[sp,#0x00]
即,将 r0 寄存器赋值为 100,然后将 r0 寄存器中的值设置到 sp + 0x00 对应的内存位置,sp 即为栈顶。因为 a
是 main() 函数中第一个定义的变量,所以正好处于栈顶。
两者对比,-O3 优化的结果是:int a = 100;
语句并没有将 a
对应的内存真正的赋值为 100,而是等到后面使用时再进行赋值(已证实),这样做的好处是,如果后续没有对 a 的访问,真正的赋值工作可以不用做了。
-O0 由于没有优化,所以 int a = 100;
语句就乖乖地将 a
对应的内存真正的赋值 100 了。
调试的时候,要使用 -O0,不然你大概率会发现程序并不是按照你预期的顺序执行的。
以上是关于gcc -O0 -O1 -O2 -O3 -Os 编译优化等级的主要内容,如果未能解决你的问题,请参考以下文章