Bithacks:确定值是否小于,大于或等于某个值

时间:2015-08-23 18:54:10

标签: c algorithm optimization bit-manipulation

我正在研究的算法必须经常检查是否有一些任意整数值' 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),它将以尽可能少的操作给我我的结果,无论是否有比特;它只需要快速。因此,如果您有任何其他我可能没有考虑过的想法,那么我也非常感谢您指出另一种解决方案。

3 个答案:

答案 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个变量xy

你会得到:

  1. 如果x<y结果为res<0
  2. 如果x>y结果为res>0
  3. 如果x==y结果为res==0
  4. 在宏

    中实现它
    #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指令的代码,以及jzjl等分支。

    只需存储值的差异,即单个值,即使是为了以后的评估,也可以保存信息,并保留您可能需要的所有元素。

答案 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或手机上的霓虹灯),因为它们可以帮助您加速代码。