用C整数快速迹象 [英] Fast sign of integer in 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:
- 性能的基础水平是非常高的。
- 消除分支在这里所做的改进性能,但不显着。
这篇关于用C整数快速迹象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!