Skip to content

Commit c459c42

Browse files
committed
Improve: Bitwise ops for branches
Replacing multiplication with XOR results in a different assembly - GCC compiles a `cmov` instead of `jmp`.
1 parent cbaf6a5 commit c459c42

File tree

1 file changed

+8
-8
lines changed

1 file changed

+8
-8
lines changed

less_slow.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -987,10 +987,10 @@ static void branch_cost(bm::State &state) {
987987
for (auto _ : state) {
988988
std::int32_t random = random_values[(++iteration) & (count - 1)];
989989
bm::DoNotOptimize( //
990-
variable = //
991-
(random & 1) //
990+
variable = // ! Fun fact: multiplication compiles to a jump,
991+
(random & 1) // ! but replacing with a bitwise operation results in a conditional move.
992992
? (variable + random)
993-
: (variable * random));
993+
: (variable ^ random));
994994
}
995995
}
996996

@@ -1017,7 +1017,7 @@ static void branch_cost_cmov(bm::State &state) {
10171017

10181018
asm volatile( //
10191019
"leal (%[var],%[rnd],1), %[sum]\n\t" // sum := variable + random
1020-
"imull %[rnd], %[var]\n\t" // var := variable * random
1020+
"xorl %[rnd], %[var]\n\t" // var := variable ^ random
10211021
"testl $1, %[rnd]\n\t" // if (random & 1) var := sum
10221022
"cmovne %[sum], %[var]\n\t"
10231023
: [var] "+r"(variable), [sum] "=&r"(sum)
@@ -1039,8 +1039,8 @@ static void branch_cost_jump(bm::State &state) {
10391039

10401040
asm volatile( //
10411041
"testl $1, %[rnd]\n\t"
1042-
"jnz 1f\n\t" // if odd -> jump to add
1043-
"imull %[rnd], %[var]\n\t" // even: var *= rnd
1042+
"jnz 1f\n\t" // if odd -> jump to add
1043+
"xorl %[rnd], %[var]\n\t" // even: var ^= rnd
10441044
"jmp 2f\n\t"
10451045
"1:\n\t"
10461046
"addl %[rnd], %[var]\n\t" // odd: var += rnd
@@ -1070,7 +1070,7 @@ static void branch_cost_csel(bm::State &state) {
10701070

10711071
asm volatile( //
10721072
"add %w[sum], %w[var], %w[rnd]\n\t" // sum := variable + random
1073-
"mul %w[var], %w[var], %w[rnd]\n\t" // var := variable * random
1073+
"eor %w[var], %w[var], %w[rnd]\n\t" // var := variable ^ random
10741074
"tst %w[rnd], #1\n\t" // if (random & 1) var := sum
10751075
"csel %w[var], %w[sum], %w[var], NE\n\t"
10761076
: [var] "+r"(variable), [sum] "=&r"(sum)
@@ -1093,7 +1093,7 @@ static void branch_cost_branch(bm::State &state) {
10931093
asm volatile( //
10941094
"tst %w[rnd], #1\n\t"
10951095
"b.ne 1f\n\t" // if odd -> jump to add
1096-
"mul %w[var], %w[var], %w[rnd]\n\t" // even: var *= rnd
1096+
"eor %w[var], %w[var], %w[rnd]\n\t" // even: var ^= rnd
10971097
"b 2f\n\t"
10981098
"1:\n\t"
10991099
"add %w[var], %w[var], %w[rnd]\n\t" // odd: var += rnd

0 commit comments

Comments
 (0)