2010-10-03 18 views
15

Quel est l'équivalent de __builtin_popcount trouvé dans GCC et Clang, pour MSVC-10?MSVC équivalent à __builtin_popcount?

+1

Lien: http://stackoverflow.com/questions/109023/best-algorithm-to-count-the-number-of-set-bits-in-a-32-bit-integer –

+0

Jetez un coup d'œil à [ ceux-ci] (http://msdn.microsoft.com/en-us/library/bb385231 (v = vs.90) .aspx) intrinsics (ou la [version SSE4] (http://msdn.microsoft.com/fr -us/library/bb531475% 28v = VS.90% 29.aspx)), sinon vous pouvez toujours utiliser quelque chose de [ici] (http://chessprogramming.wikispaces.com/Population+Count) – Necrolis

Répondre

10

En utilisant les commentaires fournis:

+0

Soyez prudent avec ceci; il ne fonctionnera pas avec les processeurs ARM ou les processeurs x86 qui ne supportent pas le jeu d'instructions ABM. – nemequ

8

Avec ce code snippet vous obtenez la commande interne GCC lors de la construction avec MSVC:

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

(Works à partir de Visual Studio 2008).

+1

C'est "_MSC_VER" non '__MSC_VER' – lz96

1

Les __popcount intrinsèques mentionnées ci-dessus ne fonctionne pas sur ARM, ou même tous les processeurs x86 (il nécessite un jeu d'instructions ABM). Vous ne devriez pas l'utiliser directement; à la place, si vous êtes sur x86/amd64, vous devez utiliser l'intrinsèque __cpuid pour déterminer à l'exécution si le processeur prend en charge popcnt. N'oubliez pas que vous ne voulez probablement pas émettre de cpuid pour chaque appel popcnt; vous voudrez stocker le résultat quelque part. Si votre code va toujours être mono-thread, c'est trivial, mais si vous devez être thread-safe, vous devrez utiliser quelque chose comme un One-Time Initialization. Cela ne fonctionnera qu'avec Windows ≥ Vista, cependant; Si vous avez besoin de travailler avec des versions plus anciennes, vous devrez utiliser les vôtres (ou utiliser quelque chose d'un tiers).

Pour les machines sans ABM (ou si la détection de l'exécution ne vaut pas la peine), il existe plusieurs versions portables au Bit Twiddling Hacks (recherchez "Jeu de bits de comptage"). Ma version préférée fonctionne pour tout type T jusqu'à 128 bits:

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 

Si vous voulez une version drop-in, vous pouvez utiliser the builtin module in portable-snippets (divulgation complète: portable-extraits est l'un de mes projets), qui devrait fonctionner à peu près partout.

+0

Pas besoin de s'enthousiasmer pour la détection du processeur. Faites-le avant de commencer les discussions, par ex. avec un static const cpuid_result = cpuid(); 'donc il s'exécute au démarrage du programme. –

+0

Version générique intéressante du bitchack popcount. (Voir https://stackoverflow.com/a/109025/224132 pour la Q & R canonique). –