24

__builtin_popcount对于 MSVC-10,GCC 和 Clang 中的等效项是什么?

4

3 回答 3

20

使用此代码片段,您可以在使用 MSVC 构建时获得 GCC 内置:

#ifdef _MSC_VER
#  include <intrin.h>
#  define __builtin_popcount __popcnt
#endif

(来自 Visual Studio 2008 的作品)。

于 2014-07-03T10:00:14.990 回答
18

使用提供的评论:

于 2015-08-03T08:19:56.943 回答
5

上面提到的__popcount内在函数不适用于 ARM,甚至所有 x86 CPU(它需要ABM指令集)。你不应该直接使用它;相反,如果您使用的是 x86/amd64,则应该使用__cpuid内在函数在运行时确定处理器是否支持popcnt.

请记住,您可能不想cpuid为每个popcnt呼叫发出一个;您需要将结果存储在某处。如果你的代码总是单线程的,这很简单,但如果你必须是线程安全的,你就必须使用类似One-Time Initialization的东西。不过,这只适用于 Windows ≥ Vista;如果您需要使用旧版本,则需要自己动手(或使用第三方的东西)。

对于没有 ABM 的机器(或者如果运行时检测不值得),Bit Twiddling Hacks有几个可移植版本(查找“Counting bits set”)。我最喜欢的版本适用于T高达 128 位的任何类型:

v = v - ((v >> 1) & (T)~(T)0/3);                           // temp
v = (v & (T)~(T)0/15*3) + ((v >> 2) & (T)~(T)0/15*3);      // temp
v = (v + (v >> 4)) & (T)~(T)0/255*15;                      // temp
c = (T)(v * ((T)~(T)0/255)) >> (sizeof(T) - 1) * CHAR_BIT; // count

如果您想要一个插入式版本,您可以使用可移植片段中的内置模块(完全公开:可移植片段是我的项目之一),它几乎可以在任何地方工作。

于 2017-03-20T20:28:28.343 回答