在条件上按位操作设置变量

时间:2014-07-30 13:38:37

标签: c++ c performance optimization bit-manipulation

我在C / C ++应用程序中有三个变量-x,y和z。我想设置x = y,当z == 3.我可以使用乘法来做到这一点:

x = y * (z == 3)

但是这是在一个大循环中调用的,IMUL需要4个CPU周期。我希望找到一个需要1个CPU周期的操作。

编辑:编译器MSVC 64位编译,Platform Win 7 64,x86架构,Ivy Bridge或Haswell。

4 个答案:

答案 0 :(得分:3)

写:

if ( z == 3 )
    x = y * 2;
else
    x = y;

(或者您编辑问题的其他任何内容)并激活您的编译器。这就是编译器的用途。你用编译器开关说出你想要的东西,编译器做得比你好。

答案 1 :(得分:2)

在二的补码上,表达式为:

(y * (z == 3)) 

与:

相同
(y & -(z == 3))

然而,令人怀疑的是,两者的表现与另一部分的表现有很大不同。请考虑使用gcc -O3 -S编译的以下代码:

int foo1 (int y, int z) { return y * (z == 3); }
int foo2 (int y, int z) { return y & -(z == 3); }
int foo3 (int y, int z) { if (z == 3) return y; else return 0; }

foo1()

    xorl    %eax, %eax
    cmpl    $3, 8(%esp)
    sete    %al
    imull   4(%esp), %eax

对于foo2(),还有一条指令(虽然它可能更便宜):

    xorl    %eax, %eax
    cmpl    $3, 8(%esp)
    sete    %al
    negl    %eax
    andl    4(%esp), %eax

但是,对于foo3(),你得到:

    xorl    %eax, %eax
    cmpl    $3, 8(%esp)
    cmove   4(%esp), %eax

虽然这是一个条件移动指令,但代码并没有那么严格。

答案 2 :(得分:1)

这必须至少有两次操作(可能是3次)。

  1. 评估z == 3
  2. 分配到x
  3. (可能)评估y + y
  4. 我能想到的最有效的方式是用三元表达式。

    x = (z == 3) ? y + y : y;
    

答案 3 :(得分:0)

简单方法

x = (z == 3) ? y : x;

复杂的方式

x = y & (-(z == 3)); // Based on -1 = 1111...11 binary