用C整数快速迹象 [英] Fast sign of integer in C

查看:116
本文介绍了用C整数快速迹象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有在C标志功能:

int sign(int x)
{
    if(x > 0) return 1;
    if(x < 0) return -1;
    return 0;
}

不幸的是,比较成本非常高,所以我需要为了减少比较的次数来修改功能。

Unfortunately, comparison cost is very high, so I need to modify function in order reduce the number of comparisons.

我试过如下:

int sign(int x)
{
    int result;
    result = (-1)*(((unsigned int)x)>>31);

    if (x > 0) return 1;

    return result;
}

在这种情况下,我只得到一次比较。

In this case I get only one comparison.

有什么办法,以避免在所有的比较?

Is there any way to avoid comparisons at all?

修改 possible复制没有给出一个问题的答案,因为所有的答案是C ++,使用比较(我应该避免的)或不返回 1 +1 0

EDIT possible duplicate does not give an answer for a question as all answers are C++, uses comparison (that I supposed to avoid) or does not return -1, +1, 0.

推荐答案

首先,整数比较是很便宜的。它的分支的,可以是昂贵的(由于分支误predictions的风险)。

First of all, integer comparison is very cheap. It's branching that can be expensive (due to the risk of branch mispredictions).

我的基准上的功能使用gcc 4.7.2一个Sandy Bridge的框,它需要大约每次通话1.2ns。

I have benchmarked your function on a Sandy Bridge box using gcc 4.7.2, and it takes about 1.2ns per call.

以下是快约25%,在约每呼叫0.9ns

The following is about 25% faster, at about 0.9ns per call:

int sign(int x) {
    return (x > 0) - (x < 0);
}

本机code的上面是完全网点:

The machine code for the above is completely branchless:

_sign:
    xorl    %eax, %eax
    testl   %edi, %edi
    setg    %al
    shrl    $31, %edi
    subl    %edi, %eax
    ret

有两件事值得指出的是:

Two things are worth pointing out:


  1. 性能的基础水平是非常高的。

  2. 消除分支在这里所做的改进性能,但不显着。

这篇关于用C整数快速迹象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆