我正在研究的算法必须经常检查是否有一些任意整数值' x'小于,大于或等于另一个任意整数值' y'。我实现它的语言是C。
一种天真的方式是使用if-then-else分支来检查这一点,但这样做不会最佳,因为处理器的分支预测器会搞乱。我试图仅使用算术/逻辑评估以及按位操作来实现此比较,但老实说,我的大脑现在卡住了。
我将调用函数f(x,y)。如果x <1,则该函数将返回1。 Ÿ; 2,如果x == y;或3,如果x>收率
我的一个想法是评估:
x = 3 * (x > y)
当x&gt;时将返回3 y,否则为0。如果x == 0,则使用一些按位运算符并且条件x == y或x <1,可以存在返回1或2的操作。 y,但我还没有找到任何这样的操作组合来实现我的需要。
最后,我正在寻找任何函数f(x,y),它将以尽可能少的操作给我我的结果,无论是否有比特;它只需要快速。因此,如果您有任何其他我可能没有考虑过的想法,那么我也非常感谢您指出另一种解决方案。
答案 0 :(得分:4)
以下表达式可以满足您的需求。
1 + (x >= y) + (x > y)
在x86-64上compiles to a fairly-efficient code using SETcc
instead of branches:
compare(int, int):
xorl %edx, %edx
cmpl %esi, %edi
setg %al
setge %dl
movzbl %al, %eax
leal 1(%rdx,%rax), %eax
ret
在ARM上:
compare(int, int):
cmp r0, r1
ite lt
movlt r0, #1
movge r0, #2
it gt
addgt r0, r0, #1
bx lr
答案 1 :(得分:2)
只需减去2个变量x
和y
。
你会得到:
x<y
结果为res<0
x>y
结果为res>0
x==y
结果为res==0
。在宏
中实现它#define Chk(x, y) ((x)-(y))
另一个优点是你可以简单地使用!
运算符来检查相等或不平等:
if (!Chk(x, y))
{
// x == y
}
else
{
// x != y
}
P.S。这与strcmp()
等许多标准函数的结果相同。
P.P.S。请考虑处理器机器指令cmp
,至少对于我所知道的所有CPU类型,执行两个操作数之间的减法并设置标志以反映结果。即使只是比较C中的两个值,也会生成具有cmp
指令的代码,以及jz
,jl
等分支。
只需存储值的差异,即单个值,即使是为了以后的评估,也可以保存信息,并保留您可能需要的所有元素。
答案 2 :(得分:1)
一个选项是:
int f(int x,int y)
{
return ((x-y)>>31)-((y-x)>>31) + 2;
}
int main(int argc, char *argv[])
{
int x,y;
for(x=-3;x<=3;x++)
for(y=-3;y<=3;y++)
printf("x=%d y=%d f(x,y)=%d\n",x,y,f(x,y));
return 0;
}
这取决于int类型是32位数量。
您可能还需要查看SIMD说明(例如x86上的SSE或手机上的霓虹灯),因为它们可以帮助您加速代码。