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
,因为
=
的运算符优先级高于按位
&