[英]Why doesn't GCC optimize away memory writes in this summation loop?
Given the following C code, why does GCC (version 10.1, x86-64, -O3) write to memory inside the loop instead of just using two registers during summation and writing the result to memory only at the end?
void sum(unsigned int l, int *as, int *r) {
r[0] = 0;
r[1] = 0;
for (int i = 0; i < l; i++) {
r[0] += as[2 * i];
r[1] += as[2 * i + 1];
}
}
在此处生成说明。
我的猜测是,这种行为与“考虑到”并发性的 GCC 有关。 您可以有另一个线程,例如在执行求和时从同一地址的 memory 读取。
这是真正的(也是唯一的)原因吗? 它甚至可能由 C 标准定义吗?
编译器不知道as
和r
是否指向同一个数组,所以不知道r[0] += as[2 * i];
不改变as[2 * i + 1]
的值,这是r[1] += as[2 * i + 1];
,对于r[0]
、 r[1]
和as
的各种元素之间的其他交互也是类似的。
您可以通过将 function 声明更改为void sum(unsigned int l, int * restrict as, int * restrict r)
来告诉编译器通过as
和r
引用的元素不重叠。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.