【发布时间】: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& 类型的参数),则不使用矢量化,并且编译器将每次迭代中更新的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&,那么arr[i]对于某些i可能指定与ret相同的对象)。 -
@T.C.这似乎是正确的原因:godbolt.org/z/324ou8。请你把它写成答案,这样我可以接受吗?
标签: c++ vectorization compiler-optimization