性能优化:编译器优化选项 -O2/-O3 究竟有多强大?

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

之前的“性能优化的一般策略及方法”一文中介绍了多种性能优化的方法。根据以往的项目经验,开启编译器优化选项可能是立竿见影、成本最低、效果最好的方式了。

这么说可能还不够直观,举个真实的例子:我所参与的自动驾驶的项目中,无需修改任何代码,仅仅增加一个 -O2 选项,进程整体的 CPU loading 可以从 50% 降到 30% 左右,某些关键函数的执行时间可以从 1700us 降低到 700us 左右。

编译器能优化能力远比你想象中的强大!往后翻翻附录,看看那些多到让人眼花的优化选项你就知道,很多的人工优化都是不必要的,编译器会做得更快,更好,更安全!人工优化,不仅会降低代码的可读性和可维护性,而且非常容易引入 bug!

实际上,不管是 -O2 还是 -O3,都是一组优化选项的集合,要知道具体做了什么,可以通过 gcc/g++ 的 -c -Q --help=optimizers 参数

例如我用的 aarch64-unknown-nto-qnx7.1.0-g++ 编译器,如果想知道加了 -O2 之后开启了哪些优化项,可以通过以下 3 条命令:

$ aarch64-unknown-nto-qnx7.1.0-g++ -c -Q -O2 --help=optimizers > /tmp/O2-opts
$ aarch64-unknown-nto-qnx7.1.0-g++ -c -Q --help=optimizers > /tmp/O-opts
$ diff /tmp/O2-opts /tmp/O-opts | grep enabled
<   -fdevirtualize                              [enabled]
<   -finline-functions-called-once              [enabled]
<   -finline-small-functions                    [enabled]
<   -foptimize-strlen                           [enabled]
<   -freorder-blocks                            [enabled]
<   -freorder-functions                         [enabled]
<   -ftree-switch-conversion                    [enabled]
<   -ftree-tail-merge                           [enabled]
...

随便看了几个,就足以感受到编译器优化选项的强大:

  • finline-xxx:内联函数,以避免函数调用开销。顺便提一句:代码中的 inline 关键字只是一个对编译器的提示,编译器会根据具体情况作出最佳的选择,无论是否有 inline 关键字
  • fdevirtualize:尝试把虚函数调用转换为直接调用,以避免虚函数导致的额外开销
  • freorder-blocks:对函数中的代码块重新排序,以减少分支数、提高代码局部性
  • freorder-functions:对对象中函数重新排序,以提升代码局部性:把经常执行的函数放到 ".text.hot" 节,不常执行的函数放到 ".text.unlikely" 节
    ...

完整的优化项很多,具体每个选项的确切解释需要查看编译器手册。

小结

  1. 如果性能不理想,先检查是否开启了编译器优化选项。这可能是最快、最有效的手段了。
  2. 编译器能优化能力远比你想象中的强大!
  3. 不要在没有开启优化选项的时候就开始盲目改代码,很多都是徒劳,甚至降低性能、引入 bug:编译器优化会做得更快、更安全
  4. 如果开了优化选项,你的程序出现问题,不要怀疑编译器,大概率是因为你的代码不规范,使用了 C/C++ “未定义”行为导致的
  5. 需要注意,在汽车领域中,对优化选项有一定的限制,比如我的项目中,编译器的 Safety Manual 明确说明了最大只支持 -O2 的优化等级

附录

授人以渔

关于这个问题,我第一开始想到的是问 ChatGPT,但是得到的结果并不满意。然后想到的是 RTFM!

man gcc

在线版本:https://manpages.org/gcc

搜索关键字 /optimiz,很快就找到了我要的答案:

性能优化:编译器优化选项 -O2/-O3 究竟有多强大?

性能优化:编译器优化选项 -O2/-O3 究竟有多强大?文章来源地址https://www.toymoban.com/news/detail-840405.html

gcc 支持的优化选项

 Optimization Options
           -faggressive-loop-optimizations -falign-functions[=n[:m:[n2[:m2]]]] -falign-jumps[=n[:m:[n2[:m2]]]] -falign-labels[=n[:m:[n2[:m2]]]]
           -falign-loops[=n[:m:[n2[:m2]]]] -fno-allocation-dce -fallow-store-data-races -fassociative-math  -fauto-profile  -fauto-profile[=path]
           -fauto-inc-dec  -fbranch-probabilities -fcaller-saves -fcombine-stack-adjustments  -fconserve-stack -fcompare-elim  -fcprop-registers
           -fcrossjumping -fcse-follow-jumps  -fcse-skip-blocks  -fcx-fortran-rules -fcx-limited-range -fdata-sections  -fdce  -fdelayed-branch
           -fdelete-null-pointer-checks  -fdevirtualize  -fdevirtualize-speculatively -fdevirtualize-at-ltrans  -fdse -fearly-inlining  -fipa-sra
           -fexpensive-optimizations  -ffat-lto-objects -ffast-math  -ffinite-math-only  -ffloat-store  -fexcess-precision=style -ffinite-loops
           -fforward-propagate  -ffp-contract=style  -ffunction-sections -fgcse  -fgcse-after-reload  -fgcse-las  -fgcse-lm  -fgraphite-identity
           -fgcse-sm  -fhoist-adjacent-loads  -fif-conversion -fif-conversion2  -findirect-inlining -finline-functions  -finline-functions-called-once
           -finline-limit=n -finline-small-functions -fipa-modref -fipa-cp  -fipa-cp-clone -fipa-bit-cp  -fipa-vrp  -fipa-pta  -fipa-profile
           -fipa-pure-const -fipa-reference  -fipa-reference-addressable -fipa-stack-alignment  -fipa-icf  -fira-algorithm=algorithm
           -flive-patching=level -fira-region=region  -fira-hoist-pressure -fira-loop-pressure  -fno-ira-share-save-slots -fno-ira-share-spill-slots
           -fisolate-erroneous-paths-dereference  -fisolate-erroneous-paths-attribute -fivopts  -fkeep-inline-functions  -fkeep-static-functions
           -fkeep-static-consts  -flimit-function-alignment  -flive-range-shrinkage -floop-block  -floop-interchange  -floop-strip-mine
           -floop-unroll-and-jam  -floop-nest-optimize -floop-parallelize-all  -flra-remat  -flto  -flto-compression-level -flto-partition=alg
           -fmerge-all-constants -fmerge-constants  -fmodulo-sched  -fmodulo-sched-allow-regmoves -fmove-loop-invariants  -fno-branch-count-reg
           -fno-defer-pop  -fno-fp-int-builtin-inexact  -fno-function-cse -fno-guess-branch-probability  -fno-inline  -fno-math-errno  -fno-peephole
           -fno-peephole2  -fno-printf-return-value  -fno-sched-interblock -fno-sched-spec  -fno-signed-zeros -fno-toplevel-reorder  -fno-trapping-math
           -fno-zero-initialized-in-bss -fomit-frame-pointer  -foptimize-sibling-calls -fpartial-inlining  -fpeel-loops  -fpredictive-commoning
           -fprefetch-loop-arrays -fprofile-correction -fprofile-use  -fprofile-use=path -fprofile-partial-training -fprofile-values
           -fprofile-reorder-functions -freciprocal-math  -free  -frename-registers  -freorder-blocks -freorder-blocks-algorithm=algorithm
           -freorder-blocks-and-partition  -freorder-functions -frerun-cse-after-loop  -freschedule-modulo-scheduled-loops -frounding-math
           -fsave-optimization-record -fsched2-use-superblocks  -fsched-pressure -fsched-spec-load  -fsched-spec-load-dangerous
           -fsched-stalled-insns-dep[=n]  -fsched-stalled-insns[=n] -fsched-group-heuristic  -fsched-critical-path-heuristic -fsched-spec-insn-heuristic
           -fsched-rank-heuristic -fsched-last-insn-heuristic  -fsched-dep-count-heuristic -fschedule-fusion -fschedule-insns  -fschedule-insns2
           -fsection-anchors -fselective-scheduling  -fselective-scheduling2 -fsel-sched-pipelining  -fsel-sched-pipelining-outer-loops
           -fsemantic-interposition  -fshrink-wrap  -fshrink-wrap-separate -fsignaling-nans -fsingle-precision-constant  -fsplit-ivs-in-unroller
           -fsplit-loops -fsplit-paths -fsplit-wide-types  -fsplit-wide-types-early  -fssa-backprop  -fssa-phiopt -fstdarg-opt  -fstore-merging
           -fstrict-aliasing -fthread-jumps  -ftracer  -ftree-bit-ccp -ftree-builtin-call-dce  -ftree-ccp  -ftree-ch -ftree-coalesce-vars
           -ftree-copy-prop  -ftree-dce  -ftree-dominator-opts -ftree-dse  -ftree-forwprop  -ftree-fre  -fcode-hoisting -ftree-loop-if-convert
           -ftree-loop-im -ftree-phiprop  -ftree-loop-distribution  -ftree-loop-distribute-patterns -ftree-loop-ivcanon  -ftree-loop-linear
           -ftree-loop-optimize -ftree-loop-vectorize -ftree-parallelize-loops=n  -ftree-pre  -ftree-partial-pre  -ftree-pta -ftree-reassoc
           -ftree-scev-cprop  -ftree-sink  -ftree-slsr  -ftree-sra -ftree-switch-conversion  -ftree-tail-merge -ftree-ter  -ftree-vectorize  -ftree-vrp
           -funconstrained-commons -funit-at-a-time  -funroll-all-loops  -funroll-loops -funsafe-math-optimizations  -funswitch-loops -fipa-ra
           -fvariable-expansion-in-unroller  -fvect-cost-model  -fvpt -fweb  -fwhole-program  -fwpa  -fuse-linker-plugin -fzero-call-used-regs --param
           name=value -O  -O0  -O1  -O2  -O3  -Os  -Ofast  -Og

aarch64-unknown-nto-qnx7.1.0-g++ 加 -O2 相较于默认不加 -O2 增加的优化选项(完整列表)

$ aarch64-unknown-nto-qnx7.1.0-g++ -c -Q -O2 --help=optimizers > /tmp/O2-opts
$ aarch64-unknown-nto-qnx7.1.0-g++ -c -Q --help=optimizers > /tmp/O-opts
$ diff /tmp/O2-opts /tmp/O-opts | grep enabled
<   -falign-labels                              [enabled]
<   -fbranch-count-reg                          [enabled]
<   -fcaller-saves                              [enabled]
<   -fcode-hoisting                             [enabled]
<   -fcombine-stack-adjustments                 [enabled]
<   -fcompare-elim                              [enabled]
<   -fcprop-registers                           [enabled]
<   -fcrossjumping                              [enabled]
<   -fcse-follow-jumps                          [enabled]
<   -fdefer-pop                                 [enabled]
<   -fdevirtualize                              [enabled]
<   -fdevirtualize-speculatively                [enabled]
<   -fexpensive-optimizations                   [enabled]
<   -fforward-propagate                         [enabled]
<   -fgcse                                      [enabled]
<   -fguess-branch-probability                  [enabled]
<   -fhoist-adjacent-loads                      [enabled]
<   -fif-conversion                             [enabled]
<   -fif-conversion2                            [enabled]
<   -findirect-inlining                         [enabled]
<   -finline-functions-called-once              [enabled]
<   -finline-small-functions                    [enabled]
<   -fipa-bit-cp                                [enabled]
<   -fipa-cp                                    [enabled]
<   -fipa-icf                                   [enabled]
<   -fipa-icf-functions                         [enabled]
<   -fipa-icf-variables                         [enabled]
<   -fipa-profile                               [enabled]
<   -fipa-pure-const                            [enabled]
<   -fipa-ra                                    [enabled]
<   -fipa-reference                             [enabled]
<   -fipa-sra                                   [enabled]
<   -fipa-vrp                                   [enabled]
<   -fisolate-erroneous-paths-dereference       [enabled]
<   -flra-remat                                 [enabled]
<   -fmove-loop-invariants                      [enabled]
<   -foptimize-sibling-calls                    [enabled]
<   -foptimize-strlen                           [enabled]
<   -fpartial-inlining                          [enabled]
<   -fpeephole2                                 [enabled]
<   -freorder-blocks                            [enabled]
<   -freorder-functions                         [enabled]
<   -frerun-cse-after-loop                      [enabled]
<   -fsched-pressure                            [enabled]
<   -fschedule-insns                            [enabled]
<   -fschedule-insns2                           [enabled]
<   -fsection-anchors                           [enabled]
<   -fshrink-wrap                               [enabled]
<   -fsplit-wide-types                          [enabled]
<   -fssa-phiopt                                [enabled]
<   -fstore-merging                             [enabled]
<   -fstrict-aliasing                           [enabled]
<   -fthread-jumps                              [enabled]
<   -ftree-bit-ccp                              [enabled]
<   -ftree-builtin-call-dce                     [enabled]
<   -ftree-ccp                                  [enabled]
<   -ftree-ch                                   [enabled]
<   -ftree-coalesce-vars                        [enabled]
<   -ftree-copy-prop                            [enabled]
<   -ftree-dce                                  [enabled]
<   -ftree-dominator-opts                       [enabled]
<   -ftree-dse                                  [enabled]
<   -ftree-fre                                  [enabled]
<   -ftree-pre                                  [enabled]
<   -ftree-pta                                  [enabled]
<   -ftree-sink                                 [enabled]
<   -ftree-slsr                                 [enabled]
<   -ftree-sra                                  [enabled]
<   -ftree-switch-conversion                    [enabled]
<   -ftree-tail-merge                           [enabled]
<   -ftree-ter                                  [enabled]
<   -ftree-vrp                                  [enabled]

到了这里,关于性能优化:编译器优化选项 -O2/-O3 究竟有多强大?的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 计算机体系结构基础知识介绍之缓存性能的十大进阶优化之编译器优化和硬件预取(六)

    处理器和主内存之间不断扩大的性能差距促使编译器编写者仔细检查内存层次结构,看看编译时优化是否可以提高性能。再次,研究分为指令缺失的改进和数据缺失的改进。接下来介绍的优化可以在许多现代编译器中找到。 有些程序具有嵌套循环,以非连续的顺序访问内存中

    2024年02月12日
    浏览(67)
  • TS编译器选项——指定编译ES版本和模块化使用规范

    compilerOptions是TS的编译器选项,主要在tsconfig.json文件中用于对ts编译为js文件时进行配置 \\\"compilerOptions\\\" : { 配置项 } 版本可以为如下版本:\\\'es3\\\', \\\'es5\\\', \\\'es6\\\', \\\'es2015\\\', \\\'es2016\\\', \\\'es2017\\\', \\\'es2018\\\', \\\'es2019\\\', \\\'es2020\\\', \\\'es2021\\\', \\\'es2022\\\', \\\'esnext\\\'. 版本可以为如下版本:\\\'none\\\', \\\'commonjs\\\', \\\'amd\\\', \\\'system\\\', \\\'u

    2024年02月04日
    浏览(50)
  • 计算机体系结构基础知识介绍之缓存性能的十大进阶优化之编译器控制的预取和利用HBM扩展内存层次(七)

    硬件预取的替代方案是编译器在处理器需要数据之前插入预取指令来请求数据。 预取有两种类型: ■ 寄存器预取将值加载到寄存器中。 ■ 高速缓存预取仅将数据加载到高速缓存。 这两种类型都可以分为有错或无错的,即预取的地址是否会导致虚拟地址错误或保护错误的异

    2024年02月13日
    浏览(52)
  • 编译器的过度优化

    编译器在进行优化的时候,可能为了效率而交换不相关的两条相邻指令的执行顺序。也就是指令重排,这也就引发了一些问题,下面就带大家看两个经典的问题。 第一个例子来自单例模式的双加锁,下面是典型的双加锁的单例模式代码: 上面的代码看起来没问题,并且采用

    2023年04月21日
    浏览(31)
  • Java编译器中的优化技术

              Java中的热点代码主要有两类,包括: 1、被多次调用的方法。 2、被多次执行的循环体。 前者很好理解,一个方法被调用得多了,方法体内代码执行的次数自然就多,它成为 “ 热点代 码 ” 是理所当然的。而后者则是为了解决当一个方法只被调用过一次或少量

    2024年02月15日
    浏览(40)
  • AI编译器-图常见优化算法-算子融合

    算子融合(Operator Fusion)是深度学习编译器中的一种优化技术,它可以将多个算子合并为一个更大的算子,以减少计算和内存访问的开销。以下是一些常见的算子融合例子: 卷积和池化融合:将卷积层和池化层融合为一个算子,减少内存访问和计算的开销。 多个全连接层融

    2024年02月10日
    浏览(47)
  • C++ | 探究拷贝对象时的一些编译器优化

    👑作者主页:@烽起黎明 🏠学习社区:烈火神盾 🔗专栏链接:C++ 在传参和传返回值的过程中,一般编译器会做一些优化,减少对象的拷贝,这个在一些场景下还是非常有用的 经过深度探索类的六大天选之子学习,我们讲到了拷贝构造一些基本概念和调用形式 经过构造函数

    2023年04月19日
    浏览(76)
  • 形象谈JVM-第三章-即时编译器优化技术

    即时编译器优化技术一览: 相信许多同学看完这个表格,脑子里面嗡嗡的,这些名字也是晦涩难懂,要实现这些优化的技术确实有比较大的难度,但是咱们只是学习,去理解这些技术,其实并不难,下面咱们直接开讲。 首先需要明确一点的,作者是为了讲解方便,使用java的

    2024年02月12日
    浏览(43)
  • 即时编译器对于字段读取及存储指令的优化是什么?

    本文隶属于专栏《100个问题搞定Java虚拟机》,该专栏为笔者原创,引用请注明来源,不足和错误之处请在评论区帮忙指出,谢谢! 本专栏目录结构和参考文献请见100个问题搞定Java虚拟机 即时编译器会优化实例字段以及静态字段访问,以减少总的内存访问数目。 具体来说,

    2023年04月08日
    浏览(66)
  • Keil5,ARM编译器 软件优化注意事项

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

    2024年02月03日
    浏览(48)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包