Fichiers d'en-tête pour les intrinsèques SIMD x86

131

Quels fichiers d'en-tête fournissent les éléments intrinsèques des différentes extensions de jeu d'instructions x86 SIMD (MMX, SSE, AVX, ...)? Il semble impossible de trouver une telle liste en ligne. Corrige moi si je me trompe.

fredoverflow
la source

Réponses:

174

Ces jours-ci, vous devriez normalement simplement inclure <immintrin.h>. Cela comprend tout.

GCC et clang vous empêcheront d'utiliser les intrinsèques pour les instructions que vous n'avez pas activées au moment de la compilation (par exemple avec -march=nativeou-mavx2 -mbmi2 -mpopcnt -mfma -mcx16 -mtune=znver1 ou autre).

MSVC et ICC vous permettra d' utiliser sans activer quoi que ce soit intrinsics au moment de la compilation, mais vous encore devraient permettre AVX avant d' utiliser intrinsics AVX.


Historiquement (avant immintrin.hde tout insérer), vous deviez inclure manuellement un en-tête pour le plus haut niveau d'intrinsèque que vous vouliez.

Cela peut toujours être utile avec MSVC et ICC pour vous empêcher d'utiliser des jeux d'instructions dont vous ne voulez pas avoir besoin.

<mmintrin.h>  MMX
<xmmintrin.h> SSE
<emmintrin.h> SSE2
<pmmintrin.h> SSE3
<tmmintrin.h> SSSE3
<smmintrin.h> SSE4.1
<nmmintrin.h> SSE4.2
<ammintrin.h> SSE4A
<wmmintrin.h> AES
<immintrin.h> AVX, AVX2, FMA

Y compris l'un de ces pulls dans tous les précédents (sauf SSE4A uniquement AMD: immintrin.hne tire pas cela)

Certains compilateurs ont également <zmmintrin.h>pour AVX512.

fredoverflow
la source
62
Ou vous pouvez simplement #include <x86intrin.h>ce qui rassemble tout ce dont vous avez besoin.
Paul R
2
zmmintrin.h a les intrinsèques AVX-512.
onitake
3
Pourquoi p, t, s et n pour SSE3 / SSSE3 / SSE4.1 et 4.2? Que représentent ces personnages?
phuclv
5
@ LưuVĩnhPhúc SSE3 = Nouvelles instructions Prescott, SSSE3 = Nouvelles instructions Tejas. Je pense que SSE4.2 et AES font référence à la famille de processeurs sur laquelle ils ont été introduits (Nehalem et Westmere)
Drew McGowen
14
N'incluez pas <zmmintrin.h>directement; gcc ne le fournit même pas. Utilisez simplement<immintrin.h> ou le plus complet <x86intrin.h>. Cette réponse est fondamentalement obsolète, sauf si vous évitez intentionnellement d'inclure des éléments intrinsèques pour les versions plus récentes de SSE car votre compilateur ne se plaint pas lorsque vous utilisez une instruction SSE4.1 lors de la compilation pour SSE2. (gcc / clang ne se plaignent, vous devriez simplement utiliser immintrin.h pour les IDK sur les autres..)
Peter Cordes
76

Sur GCC / clang, si vous utilisez uniquement

#include <x86intrin.h>

il inclura tous les en-têtes SSE / AVX qui sont activés selon les commutateurs du compilateur comme -march=haswellou juste -march=native. De plus, certaines instructions spécifiques à x86 aiment bswapou rordeviennent disponibles en tant qu'intrinsèques.


L'équivalent MSVC de cet en-tête <intrin.h>


Si vous voulez juste un SIMD portable, utilisez #include <immintrin.h>

MSVC, ICC et gcc / clang (et d'autres compilateurs comme Sun je pense) prennent tous en charge cet en-tête pour les intrinsèques SIMD documentés par le seul outil de recherche / recherche intrinsèques d'Intel: https://software.intel.com/sites/landingpage/IntrinsicsGuide /

Gunther Piez
la source
Je n'étais pas sûr, si les nouvelles versions le pourraient ... Quoi qu'il en soit, tant que gcc, icc et clang l'ont, je pense que je peux l'utiliser :-)
Gunther Piez
5
MSVC n'a pas <x86intrin.h>, mais <intrin.h>réalise un effet similaire. Vous avez toujours besoin d'une compilation conditionnelle, bien sûr. :-(
Cody Gray
Tous les principaux compilateurs x86 ont #include <immintrin.h>. Utilisez-le pour les intrinsèques SIMD. Vous n'avez besoin que du plus grand (et légèrement plus lent à compilateur) x86intrin.hou intrin.hsi vous avez besoin de trucs comme les intrinsèques de rotation d'entiers / d'analyse de bits (bien qu'Intel documente certains de ceux-ci comme étant disponibles immintrin.h dans leur guide des intrinsèques ).
Peter Cordes
IIRC, il y a des éléments intrinsèques non SIMD qu'Intel documente comme étant dans immintrin.h, mais que gcc, clang et / ou MSVC n'ont que dans x86intrin.h/ intrin.hmais pas dans immintrin.h.
Peter Cordes
56

Le nom de l'en-tête dépend de votre compilateur et de l'architecture cible.

  • Pour Microsoft C ++ (ciblant x86, x86-64 ou ARM) et Intel C / C ++ Compiler pour Windows, utilisez intrin.h
  • Pour le ciblage gcc / clang / icc x86 / x86-64, utilisez x86intrin.h
  • Pour le bras de ciblage gcc / clang / armcc avec utilisation de NEON arm_neon.h
  • Pour ARM de ciblage gcc / clang / armcc avec WMMX mmintrin.h
  • Pour gcc / clang / xlcc ciblant PowerPC avec VMX (alias Altivec) et / ou VSX altivec.h
  • Pour gcc / clang ciblant PowerPC avec utilisation SPE spe.h

Vous pouvez gérer tous ces cas avec des directives de prétraitement conditionnel:

#if defined(_MSC_VER)
     /* Microsoft C/C++-compatible compiler */
     #include <intrin.h>
#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))
     /* GCC-compatible compiler, targeting x86/x86-64 */
     #include <x86intrin.h>
#elif defined(__GNUC__) && defined(__ARM_NEON__)
     /* GCC-compatible compiler, targeting ARM with NEON */
     #include <arm_neon.h>
#elif defined(__GNUC__) && defined(__IWMMXT__)
     /* GCC-compatible compiler, targeting ARM with WMMX */
     #include <mmintrin.h>
#elif (defined(__GNUC__) || defined(__xlC__)) && (defined(__VEC__) || defined(__ALTIVEC__))
     /* XLC or GCC-compatible compiler, targeting PowerPC with VMX/VSX */
     #include <altivec.h>
#elif defined(__GNUC__) && defined(__SPE__)
     /* GCC-compatible compiler, targeting PowerPC with SPE */
     #include <spe.h>
#endif
Marat Dukhan
la source
Voici quelques autres à ajouter à votre liste: Sur UltraSPARC + VIS avec gcc, utilisez visintrin.h; si vous possédez le VSDK de Sun, vis.h propose un ensemble différent d'intrinsèques. La documentation peut être trouvée ici: Builtins GCC VIS , guide de l'utilisateur Sun VIS .
onitake
44

De cette page

+----------------+------------------------------------------------------------------------------------------+
|     Header     |                                         Purpose                                          |
+----------------+------------------------------------------------------------------------------------------+
| x86intrin.h    | Everything, including non-vector x86 instructions like _rdtsc().                         |
| mmintrin.h     | MMX (Pentium MMX!)                                                                       |
| mm3dnow.h      | 3dnow! (K6-2) (deprecated)                                                               |
| xmmintrin.h    | SSE + MMX (Pentium 3, Athlon XP)                                                         |
| emmintrin.h    | SSE2 + SSE + MMX (Pentium 4, Athlon 64)                                                  |
| pmmintrin.h    | SSE3 + SSE2 + SSE + MMX (Pentium 4 Prescott, Athlon 64 San Diego)                        |
| tmmintrin.h    | SSSE3 + SSE3 + SSE2 + SSE + MMX (Core 2, Bulldozer)                                      |
| popcntintrin.h | POPCNT (Nehalem (Core i7), Phenom)                                                       |
| ammintrin.h    | SSE4A + SSE3 + SSE2 + SSE + MMX (AMD-only, starting with Phenom)                         |
| smmintrin.h    | SSE4_1 + SSSE3 + SSE3 + SSE2 + SSE + MMX (Penryn, Bulldozer)                             |
| nmmintrin.h    | SSE4_2 + SSE4_1 + SSSE3 + SSE3 + SSE2 + SSE + MMX (Nehalem (aka Core i7), Bulldozer)     |
| wmmintrin.h    | AES (Core i7 Westmere, Bulldozer)                                                        |
| immintrin.h    | AVX, AVX2, AVX512, all SSE+MMX (except SSE4A and XOP), popcnt, BMI/BMI2, FMA             |
+----------------+------------------------------------------------------------------------------------------+

Donc, en général, vous pouvez simplement inclure immintrin.hpour obtenir toutes les extensions Intel, ou x86intrin.hsi vous voulez tout, y compris_bit_scan_forward et_rdtsc , ainsi que toutes les intrinsèques vectorielles incluent celles uniquement AMD. Si vous êtes contre l'inclusion de plus dont vous avez réellement besoin, vous pouvez choisir la bonne inclusion en regardant le tableau.

x86intrin.h est la méthode recommandée pour obtenir des éléments intrinsèques pour AMD XOP (Bulldozer uniquement, pas même les futurs processeurs AMD) , plutôt que d'avoir son propre en-tête.

Certains compilateurs généreront toujours des messages d'erreur si vous utilisez des éléments intrinsèques pour des jeux d'instructions que vous n'avez pas activés (par exemple _mm_fmadd_pssans activer fma, même si vous incluez immintrin.het activez AVX2).

RubenLaguna
la source
1
smmintrin(SSE4.1) est Penryn (45nm Core2), pas Nehalem ("i7"). Pouvons-nous arrêter d'utiliser «i7» comme nom d'architecture? Cela n'a plus de sens maintenant qu'Intel continue de l'utiliser pour la famille SnB .
Peter Cordes
immintrin.hne semble pas inclure _popcnt32et _popcnt64(à ne pas confondre avec ceux de popcntintrin.h!) intrinsèques sur GCC 9.1.0. Il semble donc que cela x86intrin.hsert toujours un objectif.
Thom Wiggers
12

Comme beaucoup de réponses et de commentaires l'ont indiqué, <x86intrin.h>est l' en-tête complet pour x86 [-64] SIMD intrinsèques. Il fournit également des instructions de prise en charge intrinsèques pour d'autres extensions ISA. gcc,, clanget iccont tous réglé sur ce point. J'avais besoin de fouiller sur les versions qui prennent en charge l'en-tête, et j'ai pensé qu'il pourrait être utile d'énumérer quelques résultats ...

  • gcc : le support pour x86intrin.happaraît en premier dans gcc-4.5.0. La gcc-4série de versions n'est plus maintenue, tandis que gcc-6.xla série de versions stables actuelle . gcc-5a également introduit l' __has_includeextension présente dans toutes les clang-3.xversions. gcc-7est en pré-version (test de régression, etc.) et suivant le schéma de version actuel, sera publié sous la forme gcc-7.1.0.

  • clang : x86intrin.hsemble avoir été pris en charge pour toutes les clang-3.xversions. La dernière version stable est clang (LLVM) 3.9.1. La branche de développement est clang (LLVM) 5.0.0. On ne sait pas ce qui est arrivé à la 4.xsérie.

  • Apple retentit : ennuyeux, le versionnage d'Apple ne correspond pas à celui des LLVMprojets. Cela dit, la version actuelle:, clang-800.0.42.1est basée sur LLVM 3.9.0. La première LLVM 3.0version basée semble être de Apple clang 2.1retour Xcode 4.1. LLVM 3.1apparaît d'abord avec Apple clang 3.1(une coïncidence numérique) dans Xcode 4.3.3.

    Apple définit également __apple_build_version__par exemple 8000042. Cela semble être le schéma de version le plus stable et strictement ascendant disponible. Si vous ne souhaitez pas prendre en charge les compilateurs hérités, définissez l'une de ces valeurs comme une exigence minimale.

Toute version récente de clang, y compris les versions Apple, ne devrait donc avoir aucun problème avec x86intrin.h. Bien sûr, gcc-5vous pouvez toujours utiliser les éléments suivants:

#if defined (__has_include) && (__has_include(<x86intrin.h>))
#include <x86intrin.h>
#else
#error "upgrade your compiler. it's free..."
#endif

Une astuce sur laquelle vous ne pouvez pas vraiment compter consiste à utiliser les __GNUC__versions dans clang. La gestion des versions est, pour des raisons historiques, bloquée 4.2.1. Une version qui précède l'en- x86intrin.htête. C'est parfois utile pour, par exemple, des extensions GNU C simples qui sont restées rétrocompatibles.

  • icc : pour autant que je sache, l'en- x86intrin.htête est pris en charge depuis au moins Intel C ++ 16.0. Le test de version peut par réalisée avec: #if (__INTEL_COMPILER >= 1600). Cette version (et peut-être des versions antérieures) fournit également un support pour l' __has_includeextension.

  • MSVC : Il semble que ce MSVC++ 12.0 (Visual Studio 2013)soit la première version à fournir l'en- intrin.htête - pas x86intrin.h ... cela suggère: #if (_MSC_VER >= 1800)comme test de version. Bien sûr, si vous essayez d'écrire du code portable sur tous ces différents compilateurs, le nom de l'en-tête sur cette plate-forme sera le moindre de vos problèmes.

Brett Hale
la source