MSVC équivalent à popcount intégré?
Quel est l'équivalent de __builtin_popcount
tel que trouvé dans GCC et Clang, pour MSVC-10?
3 réponses
utilisant les commentaires fournis:
-
__popcnt
disponible par<intrin.h>
-
_mm_popcnt_u64
avec SSE4 et<nmmintrin.h>
avec ce code snippet vous obtenez le bâtiment GCC lors de la construction avec MSVC:
#ifdef _MSC_VER
# include <intrin.h>
# define __builtin_popcount __popcnt
#endif
(œuvres de Visual Studio 2008).
le __popcount
intrinsèque mentionné ci-dessus ne fonctionne pas sur ARM, ni même sur tous les CPU x86 (Il nécessite ABM instruction set). Vous ne devriez pas l'utiliser directement; à la place, si vous êtes sur x86/amd64, vous devriez utiliser le __cpuid
intrinsèque pour déterminer à l'exécution si le processeur supporte popcnt
.
gardez à l'esprit que vous ne voulez probablement pas émettre un 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 initialisation unique . Cela ne fonctionnera qu'avec Windows ≥ Vista, cependant; si vous avez besoin de travailler avec des versions plus anciennes, vous aurez besoin de lancer votre propre (ou utiliser quelque chose d'un tiers).
pour les machines sans ABM (ou si la détection d'exécution n'en vaut pas la peine), il existe plusieurs versions portables à Peu Tourner les Hacks (cherchez "Comptage de bits"). 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 le module d'intégration dans portable-snippets (divulgation complète: portable-snippets est l'un de mes projets), qui devrait fonctionner à peu près partout.