C++ GCC和Clang在2次幂运算模式下执行极慢
考虑以下代码:C++ GCC和Clang在2次幂运算模式下执行极慢,c++,gcc,optimization,clang,mod,C++,Gcc,Optimization,Clang,Mod,考虑以下代码: int foo(int x) { if ((x) % 256 == 0) if ((x) % 16 == 0) return 0; return 1; } int bar(int x) { if ((x) & 255 == 0) if ((x) & 15 == 0) return 0; return 1; } 我认为这两个函数的汇编代码是等价的,因为GCC和Clang等现代编译器将执行%X优化,将此操作更
int foo(int x) {
if ((x) % 256 == 0)
if ((x) % 16 == 0)
return 0;
return 1;
}
int bar(int x) {
if ((x) & 255 == 0)
if ((x) & 15 == 0)
return 0;
return 1;
}
我认为这两个函数的汇编代码是等价的,因为GCC和Clang等现代编译器将执行%X
优化,将此操作更改为&(X-1)
,其中X是2的常数幂。但不幸的是,Clang似乎在进行这种优化,这是否应该成为Clang的性能问题bug
然后我将代码更改为:
int foo(int x) {
if ((x + 1) % 256 == 0)
if ((x + 1) % 16 == 0)
return 0;
return 1;
}
int bar(int x) {
if ((x + 1) & 255 == 0)
if ((x + 1) & 15 == 0)
return 0;
return 1;
}
GCC和Clang都存在巨大的性能差距,它们在函数foo
上的执行速度非常慢,即使我打开了O3
。GCC在foo
上执行是在bar
上执行,迭代次数为100000次,而在foo
上执行是在bar
上执行
在这种情况下,是否存在两个编译器都无法进行
%X
优化的问题?基本问题是,当X
的输入值为负值时,您提出的优化是错误的。如果将x
的类型更改为无符号
而不是int
,那么您将看到两个编译器都进行了此优化。括号是否正确=
的运算符优先级高于按位&
。也许问题是bar
正在计算if(x&(255==0))
而不是if((x&255)==0)
?是的,内森·皮尔森说得对,看起来你在比较不同的东西@cigien哇,这是个大错误。谢谢不用担心,每个人都会这样:)好的,是的,因为编写的bar
可以完全优化为返回1
,这显然要快得多。不,这只是一个运算符优先级问题(x+1)&255==0将首先执行255==0
,因为=
的运算符优先级高于按位&
。