Great, I'm happy to assist you with text translations. What language do you need me to translate from and to?
我使用
上述代码在编译期间进行调试。
相比之下,如果我注释掉三元运算符并取消注释
#pragma GCC target ("avx2")
#pragma GCC optimize ("O3")
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#define N (1<<20)
char a[N], b[N];
int main() {
for (int i=0; i<N; ++i) {
a[i] = rand()%100;
b[i] = rand()%100;
}
int ans = 0;
#pragma GCC ivdep
for (int i=0; i<N; ++i) {
//ans += std::min(a[i], b[i]);
ans += a[i]>b[i] ? a[i] : b[i];
}
printf("%d\n", ans);
}
我使用
gcc 9.3.0
编译,编译命令为g++ -o test test.cpp -ftree-vectorize -fopt-info-vec-missed -fopt-info-vec-optimized -funsafe-math-optimizations
。上述代码在编译期间进行调试。
test.cpp:19:17: optimized: loop vectorized using 32 byte vectors
相比之下,如果我注释掉三元运算符并取消注释
std::min
,得到的结果是这样的:test.cpp:19:17: missed: couldn't vectorize loop
test.cpp:20:35: missed: statement clobbers memory: _9 = std::min<char> (_8, _7);
看起来std::min()
做了一些不寻常的事情,这使得gcc无法理解它只是一个最小值操作。这是标准引起的吗?还是实现的问题?或者有一些编译标志可以解决这个问题?
-O1
或更高级别可以实现向量化。我怀疑这是函数内联的问题。 - Drew Dormann-O
选项,否则这些优化选项都没有任何作用。特别是没有-O
,编译器不会内联std::min
,所以它可能修改全局变量a,b
。 - Nate Eldredge#pragma GCC optimize ("O3")
相当于在每个函数上指定__attribute__((optimize("O3")))
。但我猜测这样做可能不允许像内联那样进行过程间优化,因此它可能不等同于在命令行上使用-O3
。总之,这表明实际上它们是不等效的。 - Nate Eldredge-O3
。你知道的越多,我猜。如果你把它作为答案,我会接受的。感谢你的帮助。 - Maltysen