对于branchless的改造有很多
最简单的:
if (a > b) {
a += b;
}
这种我们其实是可以改写为
a = a > b? a + b : a;
编译器会自动的帮我们编译成branchless的代码:
https://godbolt.org/z/h8rM99fo9
func(int, int):
lea eax, [rdi+rsi]
cmp edi, esi
cmovg edi, eax
...
但是二元表达式有一定的局限性,只能同时处理一个变量,对于下面这种还是会生成 jmp 指令的
if (a > b) {
a += b;
b = 0;
} else {
a = 0;
b += a;
}
改写为:
auto c = a > b? a + b : 0;
auto d = a > b? 0 : a + b;
https://godbolt.org/z/56Yxfaq48
func(int, int):
lea r8d, [rdi+rsi]
xor r9d, r9d
cmp edi, esi
jle .L2
mov r9d, r8d
xor r8d, r8d
.L2:
mov esi, r8d
mov edi, r9d
...
我们可以利用其他方法把这段代码branchless
最简单的办法就是乘法:
auto c = a + b;
auto flg = a > b;
a = flg * c + !flg * 0;
b = 0 * flg + flg * c;
标签:int,r9d,edi,r8d,condition,branchless,flg
From: https://www.cnblogs.com/stdpain/p/17450006.html