branchless condition

对于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;
posted @ 2023-06-01 19:27  stdpain  阅读(20)  评论(0编辑  收藏  举报