How can I count the number of leading zeros in a 128-bit integer (uint128_t
) efficiently?
I know GCC\'s built-in functions:
__builti
Assuming a 'random' distribution, the first non-zero bit will be in the high 64 bits, with an overwhelming probability, so it makes sense to test that half first.
Have a look at the code generated for:
/* inline */ int clz_u128 (uint128_t u)
{
unsigned long long hi, lo; /* (or uint64_t) */
int b = 128;
if ((hi = u >> 64) != 0) {
b = __builtin_clzll(hi);
}
else if ((lo = u & ~0ULL) != 0) {
b = __builtin_clzll(lo) + 64;
}
return b;
}
I would expect gcc to implement each __builtin_clzll
using the bsrq
instruction - bit scan reverse, i.e., most-significant bit position - in conjunction with an xor
, (msb ^ 63)
, or sub
, (63 - msb)
, to turn it into a leading zero count. gcc might generate lzcnt
instructions with the right -march=
(architecture) options.
Edit: others have pointed out that the 'distribution' is not relevant in this case, since the HI uint64_t needs to be tested regardless.