对多个整数中的位进行计数..有更快的方法吗
counting bits across multiple integers... is there a faster way?
我有一个4长的数组,我想计算给定范围内的集合位数。这是我目前正在使用的函数(其中bitcount(uint64_t)
是一个内联asm函数,它给出了参数中的设置位数):
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;
}
}
我发现这个代码的性能非常好,但我想知道我是否可以做些什么来加快它,或者重新设计算法是否可以提高性能。
我已经创建了两个具有零分支的不同版本,我认为应该选择David Wohlferd注释,因为它紧凑。我不相信任何分支版本会更快。处理器分支预测可以有效地消除一致数据上的跳跃。在没有分支的情况下,将一直对位计数4次(除非SSE?)。我将在这里发布我的第二个(非常短的)无分支版本。首先是复杂的比特计算。
unsigned bitcount2(const uint64_t *long_ptr, size_t begin, size_t end)
{
uint64_t mask[] = { 0, 0, 0, ~((1ULL << (begin & 63)) - 1), -1LL, -1LL, -1LL, ((1ULL << (end & 63)) - 1), 0, 0, 0 };
uint64_t* b_start = mask+(3 - begin / 64);
uint64_t* b_end = mask + (7 - end / 64);
return bitcount(long_ptr[0] & b_start[0] & b_end[0]) +
bitcount(long_ptr[1] & b_start[1] & b_end[1]) +
bitcount(long_ptr[2] & b_start[2] & b_end[2]) +
bitcount(long_ptr[3] & b_start[3] & b_end[3]);
}
相关文章:
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 让bool方法返回其他整数
- 有没有一种优雅而快速的方法来测试整数中的 1 位是否位于连续区域
- 将一系列整数放入类的最佳方法是什么?
- 比较C++中两个整数的最有效和最干净的方法是什么?
- 在 C++ 中将整数数组转换为位集表示形式的最佳方法?
- 有没有更好的方法对C++中的三个整数进行排序?
- 使用192/256位整数求和无符号64位整数向量的点积的最快方法
- 初始化不是整数的巨大常量多维数组的最佳方法是什么?
- 在C++中,将无符号整数转换为八进制表示,反之亦然的最佳方法是什么
- C++:这是使用整数变量作为函数调用指针的正确方法吗
- 计算将整数n分解为4平方和的方法的数量
- 计算机使用什么方法添加无符号整数
- 基于整数向量执行位排列的有效方法?
- 快速方法可以将整数乘以适当的分数,而无需浮点或溢出
- 为大无符号整数分配内存的有效方法
- 在模型中保存整数的方法,与QStyledItemDelegate兼容
- 将整数输入数组的方法比 scanf() 或 cin 更快?
- 如何将枚举传递给方法而不将其作为整数传递
- 获取两个无符号整数 C++ 乘积的高 32 位的有效方法