I have two functions to count the number of set '1' bits in the first offset
bits of either a 64 bit number, or a bitmap struct.
After some profiling, particularly the latter is quite a bottleneck in our system.
What can we do to make it faster?
#define POPCOUNT16(x) __builtin_popcount(x)
#define POPCOUNT64(x) __builtin_popcountl(x)
static __always_inline __constant int32 count64(int64 const bitmap, int32 const offset) {
return offset == 0 ? 0 : POPCOUNT64(bitmap & (0xffffffffffffffffUL << (64 - offset)));
}
typedef struct {
int64 hi;
int16 lo;
} __packed int80;
static __always_inline __constant int32 countBitmap(int80 const bitmap, int32 const offset) {
int32 count = 0;
if (offset > 0) {
count += POPCOUNT64(bitmap.hi & (0xffffffffffffffffUL << (sizeof (bitmap.hi)*8 - MIN(offset, sizeof (bitmap.hi)*8))));
if (offset > sizeof (bitmap.hi)*8)
count += POPCOUNT16(bitmap.lo & ((int16)0xffff << (sizeof (bitmap.hi)*8+sizeof (bitmap.lo)*8 - offset)));
}
return count;
}
count64()
takes anint64 bitmap
— how can there be abitmap.hi
? \$\endgroup\$inline __attribute__((always_inline))
, I figured it would make no difference which, so I put it in the function for simplicity. \$\endgroup\$