ARM嵌入式编译器编译优化选项 -O

这篇具有很好参考价值的文章主要介绍了ARM嵌入式编译器编译优化选项 -O。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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文章来源地址https://www.toymoban.com/news/detail-603019.html

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

到了这里,关于ARM嵌入式编译器编译优化选项 -O的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 一个关于编译器优化选项问题的解决

    因为当前项目单片机容量不够使用,打算开启编译器优化,结果在使用KEIL编译器优化后,程序在发送Modbus数据时,程序直接跑飞了 最后发现是 局部变量指针 作为了DMA的内存地址参数,导致当DMA连续搬运数据时,实际那个局部变量已经被释放,导致DMA搬运数据的过程中出现错

    2024年04月09日
    浏览(50)
  • 性能优化:编译器优化选项 -O2/-O3 究竟有多强大?

    之前的“性能优化的一般策略及方法”一文中介绍了多种性能优化的方法。根据以往的项目经验, 开启编译器优化选项 可能是立竿见影、成本最低、效果最好的方式了。 这么说可能还不够直观,举个真实的例子:我所参与的自动驾驶的项目中,无需修改任何代码,仅仅增加

    2024年03月15日
    浏览(46)
  • C++代码性能优化的好处与缺点?有哪些编译器优化选项?

    性能优化是C++编程中的一个重要方面,它可以带来许多好处,但也有一些潜在的缺点。 以下是C++代码性能优化的一些优缺点: 优点: 提高执行速度 : 优化后的代码可以更快地执行,这对于需要处理大量数据或需要快速响应的应用程序尤其重要。 减少资源消耗 : 优化可以减少

    2024年03月27日
    浏览(53)
  • Keil5,ARM编译器 软件优化注意事项

    循环是大多数程序中的常见结构。由于大量的执行时间通常花费在循环中,因此值得关注时间关键循环。 如果不谨慎地编写,环路终止条件可能会导致大量开销。在可能的情况下: 使用简单的终止条件。 写入倒计时到零循环。 使用  unsigned int  类型的计数器。 测试与零的

    2024年02月03日
    浏览(47)
  • 嵌入式:ARM常用开发编译软件介绍

    ADS(ARM Developer Suite),是在1993年由Metrowerks公司开发是ARM处理器下最主要的开发工具。 他的前身是SDT,SDT是ARM公司几年前的开发环境软件,目前SDT早已经不再升级。ADS包括了四个模块分别是:SIMULATOR;C 编译器;实时调试器;应用函数库。ADS对汇编、C/C++、java支持的均很好,

    2024年02月06日
    浏览(62)
  • 【ARM 嵌入式 编译系列 2.1 -- GCC 编译参数学习】

    请阅读 【ARM GCC 编译专栏导读】 上篇文章:ARM 嵌入式 编译系列 2 – GCC 编译过程介绍 下篇文章:ARM 嵌入式 C 入门及渐进 3 – GCC attribute ((weak)) 弱符号使用 上篇文章 ARM 嵌入式 编译系列 2 – GCC 编译过程介绍 已经介绍过了具体的编译流程,本篇文章主要介绍变过程中常见的

    2024年02月13日
    浏览(41)
  • 【ARM 嵌入式 编译系列 10.4 -- 生成二进制文件】

    在嵌入的工作中,经常会使用到二进制文件,那么我们如何自己生成一个二进制文件呢?接下来介绍如何将一个只包含将32位数据的文件转化为二进制文件,原文件如下(数据一共 64bytes): 我们使用 gcc 对齐先进行编译然后再进行反汇编: 具体命令如下: 通过上面命令会生成

    2024年02月02日
    浏览(51)
  • 【ARM 嵌入式 编译系列 3.5 -- gcc 链接参数介绍】

    请阅读 【嵌入式开发学习必备专栏 之 ARM GCC 编译专栏】 上篇文章【ARM 嵌入式 编译系列 3.4 – 查看所依赖库文件的路径 详细介绍】一直在提 链接参数 ,那么链接参数有哪些,它们又有什么作用呢? 如前一篇文章中的的链接参数到底是什么意思呢? -L : 指定了 链接库的路径

    2024年01月17日
    浏览(44)
  • 【ARM 嵌入式 编译系列 3.4 -- libgcc.a 详细介绍】

    请阅读 【嵌入式开发学习必备专栏 之 ARM GCC 编译专栏】 libgcc 是GCC的一部分。C语言不仅仅是由编译器构成,还包括了一个标准库。编译器在 GCC包里 ,标准库则位于 GNU C库里 ,即glibc包里。C编译器(cc1)肯定是要依赖 glibc库才能正常运行。 但是编译器本身还使用了一个内部

    2024年01月20日
    浏览(44)
  • 【ARM 嵌入式 编译系列 10.3 -- GNU elfutils 工具小结】

    请阅读 【ARM GCC 编译专栏导读】 上篇文章:【ARM 嵌入式 编译系列 10.2 – 符号表与可执行程序分离详细讲解】 下篇文章:【ARM 嵌入式 编译系列 11 – GCC attribute ((packed))详细介绍】 GNU elfutils是一个开源的工具集,用于处理 ELF (Executable and Linkable Format)格式的可执行文件、

    2024年02月13日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包