我的代码有很多类似的模式
int a, b.....
bool c = x ? a >= b : a <= b;
,对于其他不平等比较运算符也类似。有没有一种方法可以编写此代码以实现x86的更好性能/无分支。
请为我提供have you benchmarked your code? Is this really your bottleneck?
类型的注释。我要求其他方式编写此代码,以便可以进行基准测试。
编辑:
bool x
答案 0 :(得分:2)
原始表达:
x ? a >= b : a <= b
无分支等效表达式,无短路评估:
!!x & a >= b | !x & a <= b
这是不使用算术欺骗手段的通用模式的示例。注意操作员的优先级;对于更复杂的示例,您可能需要括号。
答案 1 :(得分:2)
另一种方式是:
bool c = (2*x - 1) * (a - b) >= 0;
这会在此处生成无分支的代码:https://godbolt.org/z/1nAp7G
#include <stdbool.h>
bool foo(int a, int b, bool x)
{
return (2*x - 1) * (a - b) >= 0;
}
------------------------------------------
foo:
movzx edx, dl
sub edi, esi
lea eax, [rdx-1+rdx]
imul eax, edi
not eax
shr eax, 31
ret
答案 2 :(得分:1)
您当前拥有的方式可能是无与伦比的。
但是对于正整数a
和b
和bool
x
,您可以使用
a / b * x + b / a * !x
(您可以使用a
替换a + 1
,并在需要支持零的情况下类似地替换b
,以适应额外的CPU消耗。)
答案 3 :(得分:1)
由于您只是在寻找等效的表达式,所以这来自修补@AlexanderZhang的注释:
(a==b) || (c != (a<b))
答案 4 :(得分:-1)
如果a> = b,则a-b将为正,并且第一位(符号位)为0。否则a-b为负,并且第一位为1。 因此,我们可以简单地“异或” a-b的第一位和x的值
constexpr auto shiftBit = sizeof(int)*8-1;
bool foo(bool x, int a, int b){
return x ^ bool((a-b)>>shiftBit);
}
foo(bool, int, int):
sub esi, edx
mov eax, edi
shr esi, 31
xor eax, esi
ret