我有一个由4个长整型组成的数组,我想在给定范围内计算设置位数的数量。这是我目前正在使用的函数(其中bitcount(uint64_t)
是一个内联汇编函数,用于计算参数中设置的位数):
unsigned count_bits(const uint64_t *long_ptr, size_t begin, size_t end)
{
uint64_t start_mask = ~((1L << (begin & 63)) - 1);
uint64_t end_mask = ((1L << (end & 63)) - 1);
if (begin >= 0 && begin < 64) {
if (end < 64) {
return bitcount(long_ptr[0] & start_mask & end_mask);
} else if (end < 128) {
return bitcount(long_ptr[0] & start_mask) + bitcount(long_ptr[1] & end_mask);
} else if (end < 192) {
return bitcount(long_ptr[0] & start_mask) + bitcount(long_ptr[1]) + bitcount(long_ptr[2] & end_mask);
} else if (end<256) {
return bitcount(long_ptr[0] & start_mask) + bitcount(long_ptr[1]) + bitcount(long_ptr[2]) + bitcount(long_ptr[3] & end_mask);
} else {
return bitcount(long_ptr[0] & start_mask) + bitcount(long_ptr[1]) + bitcount(long_ptr[2]) + bitcount(long_ptr[3]);
}
} else if (begin >= 64 && begin < 128) {
if (end < 128) {
return bitcount(long_ptr[1] & start_mask & end_mask);
} else if (end < 192) {
return bitcount(long_ptr[1] & start_mask) + bitcount(long_ptr[2] & end_mask);
} else if (end < 256) {
return bitcount(long_ptr[1] & start_mask) + bitcount(long_ptr[2]) + bitcount(long_ptr[3] & end_mask);
} else {
return bitcount(long_ptr[1] & start_mask) + bitcount(long_ptr[2]) + bitcount(long_ptr[3]);
}
} else if (begin >= 128 && begin < 192) {
if (end < 192) {
return bitcount(long_ptr[2] & start_mask & end_mask);
} else if (end < 256) {
return bitcount(long_ptr[2] & start_mask) + bitcount(long_ptr[3] & end_mask);
} else {
return bitcount(long_ptr[2] & start_mask) + bitcount(long_ptr[3]);
}
} else if (begin<256) {
if (end < 256) {
return bitcount(long_ptr[3] & start_mask & end_mask);
} else {
return bitcount(long_ptr[3] & start_mask);
}
} else {
return 0;
}
}
我发现这段代码的性能相当不错,但我想知道是否有什么方法可以使它运行更快,或者重新设计算法是否能提高性能。
1ULL
开头,而不是1L
。 - M.Massert(begin <= end && end < 256); uint32_t tb = begin / 64; uint32_t te = end / 64; uint32_t ret = 0; uint64_t r; for (r = long_ptr[tb] & start_mask; tb < te ; tb++, r = long_ptr[tb]) { ret += bitcount(r); } return ret + bitcount(r & end_mask);
。虽然OP代码避免了循环,但我认为这段代码没有更多的比较/跳转。而且因为它更小,可能不会占用太多的代码缓存。无论如何,值得进行基准测试。 - David Wohlferd