我在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。
答案 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次)。
z == 3
x
。y + y
我能想到的最有效的方式是用三元表达式。
x = (z == 3) ? y + y : y;
答案 3 :(得分:0)
简单方法
x = (z == 3) ? y : x;
复杂的方式
x = y & (-(z == 3)); // Based on -1 = 1111...11 binary