Counting the number of leading zeros in a 128-bit integer

后端 未结 3 833
日久生厌
日久生厌 2021-01-06 03:40

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
3条回答
  •  广开言路
    2021-01-06 04:24

    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.

提交回复
热议问题