位操作:计算uint64_t中所有位(也称为1' s)的和

时间:2014-11-17 13:00:02

标签: c++ bit-manipulation

在C ++中,我想计算uint64_t

中的1位数
# A few examples in uint8_t:
0b00000000  ==> 0
0b01000001  ==> 2
0b00110101  ==> 4
0b11111111  ==> 8

我需要执行很多(比如数百万)这样的操作,有没有快速的方法(可能有一些预处理)?

我能想到的一种可能性是为每个N位创建一个查找表(比如N=8),并为64/N执行uint64_t次查找。有更好的解决方案吗?如果我决定采用上述方法,我该如何设置N? (据我所知,即使忽略所有预处理计算,情况也不是更大的N越好,因为查找速度实际上取决于查找表是否适合缓存? )

非常感谢!

2 个答案:

答案 0 :(得分:5)

最快的方式是GCC和Clang的__builtin_popcountll和VC ++的_mm_popcnt_u64
当使用适当的标志(例如-march=native)进行编译时,这应该产生最佳性能,因为内在函数被简化为与SSE 4.2一起引入的汇编指令POPCNTDemo

如果不适用,请使用查找表尝试Bit twiddling Hack

答案 1 :(得分:1)

popcnt(人口数)指令,这很可能是获得1位数的最快方法。
请注意,您的处理器必须支持SSE4.2 你可以同时使用内在函数和内置函数,但我建议使用内在函数,因为它们得到了所有主要编译器的支持:

#include "nmmintrin.h"
auto bitsOn = _mm_popcnt_u64(10);