Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optimising "i = b ? (i | mask) : (i & ~mask)"

I want to be able to set or clear (multiple) bits of a uintX_t t.

i is a runtime variable (uintX_t). b is a runtime variable (uintX_t) which is constrained to be 0 or 1.

mask is a compile-time constant.

Is there a better way than:

i = b ? (i | mask) : (i & ~mask)

I'm looking to avoid branching, if that's possible. Target is ARM, if it matters.

like image 892
fadedbee Avatar asked Dec 03 '22 14:12

fadedbee


2 Answers

Exploiting the fact that -1u is the value with all bits set:

i = (i & ~mask) | (mask & -b);

or

i ^= (i ^ -b) & mask;

The second approach reduces the number of operations and code size. The first approach may still be faster on a superscalar architecture because some operations can be executed in parallel.

like image 169
nwellnhof Avatar answered Dec 14 '22 08:12

nwellnhof


Another alternative: Always set bits to 0 (left part) and optionally set bits to 1 (right part).

i = (i & ~mask) | (mask * b);
like image 40
user694733 Avatar answered Dec 14 '22 08:12

user694733