【问题标题】:Computation is optimized only if variable updated in loop is local仅当循环中更新的变量是本地的时才优化计算
【发布时间】:2019-01-14 07:34:21
【问题描述】:

对于下面的函数,优化的代码是向量化的,计算是在寄存器中执行的(返回值在eax中返回)。生成的机器代码例如在这里:https://godbolt.org/z/VQEBV4

int sum(int *arr, int n) {
  int ret = 0;
  for (int i = 0; i < n; i++)
    ret += arr[i];
  return ret;
}

但是,如果我将ret 变量设为全局变量(或int&amp; 类型的参数),则不使用矢量化,并且编译器将每次迭代中更新的ret 存储到内存中。机器码:https://godbolt.org/z/NAmX4t.

int ret = 0;

int sum(int *arr, int n) {
  for (int i = 0; i < n; i++)
    ret += arr[i];
  return ret;
}

我不明白为什么在后一种情况下会阻止优化(寄存器中的向量化/计算)。没有线程,即使增量也不是原子执行的。此外,这种行为似乎在编译器(GCC、Clang、Intel)之间是一致的,所以我相信它一定是有原因的。

【问题讨论】:

  • 尝试使变量static 或匿名命名空间的成员。请记住,C++ 编译器实际上只处理translation units。即使编译器可以看到在当前翻译单元中没有任何东西阻止某些优化,它对其他翻译单元一无所知。
  • @Someprogrammerdude 那么,编译器是否需要假设可以从多个翻译单元同时访问具有外部链接的非易失性非原子变量
  • 我不记得 C++ 规范对这件事说了些什么(或者我会写一个正确的答案),但由于编译器不知道其他任何东西,这似乎是一个合理的假设。
  • 别名。 arr 可能指向 ret(如果您使用 int&amp;,那么 arr[i] 对于某些 i 可能指定与 ret 相同的对象)。
  • @T.C.这似乎是正确的原因:godbolt.org/z/324ou8。请你把它写成答案,这样我可以接受吗?

标签: c++ vectorization compiler-optimization


【解决方案1】:

如果ret 不是本地的而是全局的,arr 可能会别名为ret,从而减少优化机会。

【讨论】:

  • 实验证明,本地retint* __restrict arr 生产相同的组件:demo
猜你喜欢
  • 2019-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-04
  • 2017-09-01
  • 1970-01-01
  • 2018-07-12
  • 1970-01-01
相关资源
最近更新 更多