Arm嵌入式编译器可以执行一些优化来减少代码量并提高应用程序的性能。不同的优化级别有不同的优化目标,不仅如此,针对某个目标进行优化会对其他目标产生影响。比如想减小生成的代码量,势必会影响到该代码的性能。所以优化级别总是这些不同目标(代码量,程序性能,debug信息)之间的权衡。

目录

Optimization level -O0

Optimization level -O1

Optimization level -O2

Optimization level -O3

Optimization level -Os

Optimization level -Oz

Optimization level -Omin

Optimization level -Ofast

Optimization level -Omax


Arm Compiler for Embedded提供了各种优化级别来控制不同的优化目标:

优化目标 可用的优化级别
更小的代码量 -Oz-Omin
更快的性能 -O2-O3-Ofast-Omax
兼顾代码量和debug信息 -O1
源代码和生成代码之间更好的相关性 -O0 (no optimization)
更快的编译和构建时间 -O0 (no optimization)
在代码量和性能之间的平衡 -Os
  • 如果对性能使用更高的优化级别,那么它对其他目标的影响也会更大,例如调试体验降低、代码大小增加和编译和构建时间增加。
  • 如果优化目标是减少代码大小,那么它会对其他目标产生影响,例如降低调试体验、降低性能和增加编译和构建时间。

所以用户可以根据自己的编译目标,选择适合自己的编译优化等级:

Optimization level -O0

-O0 将禁用所有优化

这个优化级别是默认的。使用-O0的结果是更快的编译和构建时间,但产生的代码,其性能比其他优化级别低,代码大小和堆栈使用也会明显高于其他优化级别。由于没有任何优化,所以生成的代码与源代码密切相关,这导致生成的代码明显更多,包括死代码(dead code)。

Optimization level -O1

-O1在编译器中启用内核优化(core optimizations)。-O1便于用户调试,代码质量优于-O0。此外,堆栈的使用也比使用-O0时得到了改善。如果想调试程序,建议使用-O1来获取更多的调试信息。与使用-O0相比,使用-O1的不同之处在于:

  • 启用了优化,这可能会降低调试信息的保真度(fidelity)。
  • 启用了内联,这意味着函数调用栈的回溯,可能不会像阅读源代码那样,具有层级关系,内联会把函数体直接加载到函数调用的地方。
  • 如果不需要函数返回的结果,则一个没有副作用的函数在预期的地方可能不会被调用,甚至会被忽略。
  • 局部变量的值在不再使用后可能无法在其作用域中被获取使用。例如,它们所在栈位置可能已经被其他模块使用了。

Optimization level -O2

与-O1相比,-O2对性能进行了更高的优化。这一层是编译器自动生成矢量指令(vector instructions)的第一个优化层。它还降低了调试体验,并且可能导致代码量的增加。与使用- O1相比,使用-O2的不同之处在于:

  • 增加内联函数调用的阈值。
  • 执行的循环展开次数可能会增加。
  • 矢量指令可以为简单循环和独立标量操作的相关序列生成。可以使用armclang命令行选项-fno-vectorize来禁止矢量指令的创建。

Optimization level -O3

与-O2相比,-O3是更高的性能优化。此优化级别需要大量编译时分析和资源的优化,-O3指示编译器优化生成代码的性能,而忽略生成代码的量,这可能导致代码量增加。与-O2相比,它还降低了调试体验。并且:

  • 增加内联函数调用的阈值。
  • 执行的循环展开次数可能会增加。
  • 在编译器流水线上,实施更加激进的指令优化策略。

Optimization level -Os

-Os的目标在不显著增加代码大小的情况下提供高性能。取决于用户的代码,-Os提供的性能可能与-O2或-O3相似。与-O3相比,-Os减少了代码量。与-O1相比,它还降低了调试体验。与使用-O3相比,使用-Os的不同之处在于:

  • 降低了内联函数调用的阈值。
  • 执行的循环展开的数量显著降低。

Optimization level -Oz

-Oz的目标是在不使用链接时间优化(LTO)的情况下提供更小的代码量。如果LTO不适合用户的应用程序,Arm建议可以使用此选项以获得最佳代码大小。与-O1相比,此优化级别降低了调试体验。与使用-Oz相比:

  • 编译器只针对代码大小进行优化,而忽略性能优化,这可能导致代码变慢。
  • 未禁用函数内联。在某些情况下,内联可以减少总体代码大小,例如,如果一个函数只被调用一次。
  • 禁止一些可能增加代码量的优化,比如将循环展开,循环矢量化等。
  • 针对M系列的AArch32以及其他的AArch64目标,将使能外联(outlining)功能。外联器(outliner )将搜索代码中相同sequence的代码,并将它们放在同一个函数当中,然后用调用同一个函数的方式来取代这些相同的代码段。外联可以减小代码大小,但是增加了代码执行时间。用户可以使用-moutline, -mno-outline选项来手动开启或者关闭该功能。

Optimization level -Omin

通过使用LTO功能的子集,-Omin旨在提供比-Oz更小的代码量。与使用-Oz相比,使用-Omin的不同之处在于:

  • -Omin支持一组基本的LTO,旨在删除未使用的代码和数据,同时还尝试优化全局内存访问。
  • -Omin支持消除虚函数(C++)。

如果希望在-Omin下进行编译,并使用单独的编译和链接步骤,那么还必须在armlink命令行中包含-Omin。

Optimization level -Ofast

-Ofast执行-O3级的优化,包括那些使用armclang选项-ffast-math执行的优化。该级别还执行其他可能违反严格遵守语言标准的激进优化。与-O3相比,此级别降低了调试体验,并且可能导致代码大小增加。

Optimization level -Omax

-Omax执行最大优化,并专门针对性能优化。它支持从-Ofast到LTO的所有优化。在这个优化级别上,Arm嵌入式编译器可能会违反严格遵守语言标准。使用此优化级别可以获得最快的性能。与-Ofast相比此级别降低了调试体验,并且可能导致代码大小增加。如果用户希望在-Omax下进行编译,并且有单独的编译和链接步骤,那么您还必须在armlink命令行中包含-Omax。

示例

int test()
{int x=10, y=20;int z;z=x+y;return 0;
}

在上述代码中,int x=10 z=x+y ,两行代码为死代码(dead code),如果使用-O0,则不进行任何优化,这两行将会被编译生成到源文件中:

armclang --target=arm-arm-none-eabi -march=armv7-a -O0 -S file.c

如果使用-O1,这两行将会被忽略:

armclang --target=arm-arm-none-eabi -march=armv7-a -O1 -S file.c

Selecting optimization optionshttps://developer.arm.com/documentation/100748/0620/Using-Common-Compiler-Options/Selecting-optimization-options?lang=en

ARM嵌入式编译器编译优化选项 -O相关推荐

  1. ARM嵌入式编译器-volatile关键字对编译器优化的影响

    volatile限定符告知计算机,其他agent(而不是变量所在的程序)可以改变该变量的值.通常它被用于硬件地址以及在其他程序或同时运行的线程中共享数据.要求编译器不要对其描述的对象作优化处理,对它的 ...

  2. Visual Studio 编译优化选项:Debug与Release、禁止优化与O1、O2、Ox优化

    Debug与禁止优化 Debug模式是调试模式,会有很多冗余的调试代码,供开发者调试程序使用. VS是默认使用Debug模式的,我使用的是VS 2017. 在Debug模式下,是默认开启禁止优化的,我 ...

  3. linux gcc g++编译命令选项

    gcc/g++在执行编译工作的时候,总共需要4步 1.预处理,生成.i的文件[预处理器cpp] 2.将预处理后的文件不转换成汇编语言,生成文件.s[编译器egcs] 3.有汇编变为目标代码(机器代码) ...

  4. 【GCC编译优化系列】究竟什么样的代码会导致函数调用的栈溢出呢?

    [GCC编译优化系列]究竟什么样的代码会导致函数调用的栈溢出呢? 一段看似铁定栈溢出的函数代码,它一定会溢出吗? 文章目录 1 问题现场 2 简单分析 3 深入分析 3.1 假如不考虑编译优化的情况 ...

  5. gcc 优化选项 -O1 -O2 -O3 -Os 优先级,-fomit-frame-pointer(不积跬步无以至千里)

    -fomit-frame-pointer 在优化时候被启用,带来了效率的提升.看到一篇比较详细记录编译选项的文章,转发一下,同时给自己作一下备忘. 少优化->多优化: O0 -->> ...

  6. gcc 优化选项 -O1 -O2 -O3 -Os 优先级

    Gcc 编译优化简介 gcc 提供了为了满足用户不同程度的的优化需要,提供了近百种优化选项,用来对{编译时间,目标文件长度,执行效率}这个三维模型进行不同的取舍和平衡.优化的方法不一而足,总体上将有以 ...

  7. GNU编译优化级别-O -O1 -O2 -O3

    最近做一个算法的GPU加速,发现实际上使用gcc的-O3(最高级编译优化)选项,可以获得很高的加速比,我的程序里达到了3倍的样子,有时效果甚至比GPU加速好.因此小小学习了下GNU的编译优化. 附言一 ...

  8. makefile工作笔记0002---gcc -O0 -O1 -O2 -O3 四级优化选项及每级分别做什么优化

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 相关博客http://blog.chinaunix.net/uid-24954950-id-295 ...

  9. gcc -O0 -O1 -O2 -O3 四级优化选项及每级分别做什么优化【转】

    转自:http://blog.csdn.net/qinrenzhi/article/details/78334677 相关博客http://blog.chinaunix.net/uid-2495495 ...

最新文章

  1. 在CentOS 6.9 x86_64的OpenResty 1.13.6.1上使用LuaRocks示例
  2. 消除类游戏ccf c语言,ccf试题 消除类游戏
  3. python监控端口_python3 端口监控
  4. linux显卡驱动版本最好,Linux 用户如何安装 Nvidia 331.67 显卡驱动稳定版本
  5. unity重定向_unity3D游戏开发之动画混合与动画重定向
  6. 《面向模式的软件体系结构2-用于并发和网络化对象模式》读书笔记(13)--- 线程安全接口和双检查加锁优化...
  7. 天,又有人找我帮忙!
  8. python如何用matplotlib绘图_Python绘图的多图控制(使用Matplotlib),python,利用,matplotlib...
  9. Java讲课笔记23:Map接口及其实现类
  10. 一张图看懂UML 类图
  11. PostGreSql工作笔记003---在Navicat中创建数据库时报错rolcatupdate不存在_具体原因看其他博文_这里使用pgAdmin4创建管理postgre
  12. Zabbix(六) zabbix主动模式监控
  13. 部分公务员已领数字货币工资,数字货币或年内扩大试点,支付宝、微信支付还会有优势吗?
  14. [系统安全] 十三.熊猫烧香病毒IDA和OD逆向分析(中)病毒释放机理
  15. A Hierarchical Latent Variable Encoder-Decoder Model for Generating Dialogues论文笔记
  16. 前端页面设置重置按钮或刷新按钮
  17. 计算机网络考研_概述
  18. js中 数组的操作 push(),pop(),shift(),unshift() 简介
  19. 计算机英语第五版翻译,计算机专业英语教程第5版翻译
  20. ybt1003:对齐输出

热门文章

  1. 笔记本电脑更换硬盘和内存
  2. CNCF LFX Mentorship:从对密码学一无所知到在 WasmEdge 中实现 wasi-crypto
  3. ROS 移动机器人 STM32 Kinect2 智能车
  4. 从量化角告你见技术指标到底能不能赚钱
  5. 五大原因!为何要将Jupyter Notebook转换为python脚本?
  6. 日常英语口语练习-情景交际场景25(三)
  7. SQL Server返回插入数据的ID和受影响的行数
  8. JS把对象赋值给另一个对象,一方发生变化另一个不受影响
  9. mysql values_values在数据库中是什么意思?
  10. 测试工程师必备武器之“军工六性”