【问题标题】:Will compiler automatically optimize repeating code?编译器会自动优化重复代码吗?
【发布时间】:2017-08-03 11:45:44
【问题描述】:

如果我有一些重复多次的简单算术代码。编译器会自动优化吗?

这里是例子:

someArray[index + 1] = 5;
otherArray[index + 1] = 7;

从性能的角度来看引入变量nextIndex = index + 1 是否有意义(而不是从良好的可读性和可维护性代码的角度来看)或者编译器会自动进行此类优化?

【问题讨论】:

  • 好吧,如果索引是基本的整数类型,很可能会启用优化。
  • 为什么不启用优化并检查生成的代码?
  • 编译并检查程序集。可以想象,但我对此表示怀疑。
  • @specializt 这些不是被索引的同一个对象。即使它们是,非内联重载 operator [] 也可能会关闭优化器。
  • 哦……看错了。

标签: c++ optimization compiler-optimization


【解决方案1】:

您不必担心像这样微不足道的优化,因为几乎所有编译器都会持续 10-15 年或更长时间。

但是,如果您的代码中有一个非常关键的位置,并且想要获得最大的运行速度,那么您可以检查生成的汇编代码以确保编译器完成了这种微不足道的优化。

在某些情况下,一个算术加法可能比保存在寄存器或内存中更快的代码版本,编译器知道这一点。如果您尝试手动优化琐碎的案例,您可以让您的代码变慢。

您可以使用https://gcc.godbolt.org等在线服务来检查生成的代码(支持gcc、clang、icc多个版本)。

【讨论】:

    【解决方案2】:

    这句古老的格言“吸一口,看看”在这里似乎很合适。我们经常忘记,到目前为止,最常见的处理器是 4/8/16 位微控制器,具有奇怪而美妙的特定于应用程序的架构,以及与之配套的适当奇怪的供应商特定编译器。他们经常有编译器扩展来“帮助”(或混淆)编译器生成“更好”的代码。

    2000 年代初期的一个 DSP 在一个流水线中并行执行每个时钟周期 8 条指令(复杂 - “加载+增量+乘法+加法+轮次”)。这样做的前提条件是必须事先将所有内容预加载到寄存器中。这意味着寄存器显然很昂贵(一如既往)。使用这种架构,最好将结果合并到空闲寄存器并使用无法并行的空闲槽(某些指令排除在同一周期中使用其他指令)稍后重新计算它。编译器是否得到了这个“正确”?是的,它经常保留结果以供以后重用,结果由于缺少寄存器而导致流水线停止,从而导致执行速度变慢。

    因此,您对其进行了编译、检查、分析等,以确保当编译器“正确”得到它时,我们可以进入并修复它。如果没有语言不支持的额外语义信息,真的很难知道什么是“正确”。

    结论:吸一口,看看

    【讨论】:

      【解决方案3】:

      是的。这是一个常见的优化。 https://en.wikipedia.org/wiki/Common_subexpression_elimination

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-04-22
        • 2013-01-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-30
        相关资源
        最近更新 更多