在C ++中,我想计算uint64_t
# A few examples in uint8_t:
0b00000000 ==> 0
0b01000001 ==> 2
0b00110101 ==> 4
0b11111111 ==> 8
我需要执行很多(比如数百万)这样的操作,有没有快速的方法(可能有一些预处理)?
我能想到的一种可能性是为每个N
位创建一个查找表(比如N=8
),并为64/N
执行uint64_t
次查找。有更好的解决方案吗?如果我决定采用上述方法,我该如何设置N
? (据我所知,即使忽略所有预处理计算,情况也不是更大的N
越好,因为查找速度实际上取决于查找表是否适合缓存? )
非常感谢!
答案 0 :(得分:5)
最快的方式是GCC和Clang的__builtin_popcountll
和VC ++的_mm_popcnt_u64
。
当使用适当的标志(例如-march=native
)进行编译时,这应该产生最佳性能,因为内在函数被简化为与SSE 4.2一起引入的汇编指令POPCNT。 Demo
如果不适用,请使用查找表尝试Bit twiddling Hack。
答案 1 :(得分:1)
有popcnt
(人口数)指令,这很可能是获得1位数的最快方法。
请注意,您的处理器必须支持SSE4.2
你可以同时使用内在函数和内置函数,但我建议使用内在函数,因为它们得到了所有主要编译器的支持:
#include "nmmintrin.h"
auto bitsOn = _mm_popcnt_u64(10);