Fichiers d'en-tête pour x86 SIMD intrinsics
qui fournit les fichiers d'en-tête intrinsèques pour les différentes extensions D'instructions SIMD x86 (MMX, SSE, AVX,...)? Il semble impossible de trouver une telle liste en ligne. Corrigez-moi si je me trompe.
5 réponses
<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
<zmmintrin.h> AVX512
si vous utilisez juste
#include <x86intrin.h>
il comprendra tous les en-têtes SSE/AVX qui sont activés selon les commutateurs de compilateur comme -march=corei7
ou tout simplement -march=native
. De plus, certaines instructions spécifiques à x86 comme bswap
ou ror
deviennent disponibles en tant qu'intrinsèques.
le nom de l'en-tête dépend de votre compilateur et de l'architecture cible.
- Pour Microsoft C++ (ciblage, x86, x86-64 ou du BRAS) et Intel Compilateur C/C++ pour Windows, utilisez
intrin.h
- Pour gcc/clang/cpi ciblage x86/x86-64 utilisation
x86intrin.h
- Pour gcc/clang/armcc ciblant les BRAS avec des NÉONS utiliser
arm_neon.h
- Pour gcc/clang/armcc ciblage BRAS avec WMMX utiliser
mmintrin.h
- Pour gcc/clang/xlcc ciblage PowerPC avec VMX (aka Altivec) et/ou VSX utiliser
altivec.h
- Pour gcc/clang ciblage PowerPC avec SPE utiliser
spe.h
vous pouvez traiter 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
de ce 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.h
pour obtenir toutes les extensions Intel , ou x86intrin.h
si vous voulez tout, y compris _bit_scan_forward
et _rdtsc
, ainsi que tous les vecteurs intrinsèques comprennent ceux qui ne sont QU'AMD. Si vous êtes contre inclure plus que vous avez réellement besoin, alors vous pouvez choisir la bonne inclusion en regardant la table.
x86intrin.h
est le recommandé façon d'obtenir intrinsèques pour AMD XOP (Bulldozer-seulement , pas même les futurs CPU AMD) , plutôt que d'avoir son propre en-tête.
certains compilateurs généreront quand même des messages d'erreur si vous utilisez des ensembles d'instructions intrinsèques que vous n'avez pas activés (par exemple _mm_fmadd_ps
sans activer fma, même si vous incluez immintrin.h
et activez AVX2).
comme beaucoup de réponses et de commentaires ont indiqué, <x86intrin.h>
est le en-tête complet pour x86[-64] SIMD intrinsics. Il fournit également des instructions intrinsèques pour supporter d'autres extensions ISA. gcc
, clang
, et icc
ont tous réglé sur ce. J'ai eu besoin de faire quelques recherches sur les versions qui soutiennent l'en-tête, et j'ai pensé qu'il pourrait être utile d'énumérer quelques résultats...
-
gcc : le support de
x86intrin.h
apparaît pour la première fois dansgcc-4.5.0
. La série de versionsgcc-4
n'est plus maintenue, tandis quegcc-6.x
est la série de versions stables current .gcc-5
a également introduit l'extension__has_include
présente dans toutes les versionsclang-3.x
.gcc-7
est en pré-version (tests de régression, etc.) et suivant la version actuelle régime, sera publié en tant quegcc-7.1.0
.
-
clang :
x86intrin.h
semble avoir été supporté pour toutes les versionsclang-3.x
. La dernière version stable estclang (LLVM) 3.9.1
. La direction du développement estclang (LLVM) 5.0.0
. On ne sait pas ce qui est arrivé à la série4.x
.
-
Apple clang : fâcheusement, la version D'Apple ne correspond pas à celle des projets
LLVM
. Cela dit , la version actuelle:clang-800.0.42.1
, est basée surLLVM 3.9.0
. La première versionLLVM 3.0
semble êtreApple clang 2.1
de retour dansXcode 4.1
.LLVM 3.1
apparaît pour la première fois avecApple clang 3.1
(une coïncidence numérique) dansXcode 4.3.3
.
Pomme définit également__apple_build_version__
par exemple,8000042
. Cela semble à propos du schéma de version le plus stable, strictement Ascendant disponible. Si vous ne voulez pas prendre en charge les compilateurs traditionnels, faites de l'une de ces valeurs une exigence minimale.
toute version récente de clang
, y compris les versions Apple, ne devrait donc pas avoir de problème avec x86intrin.h
. Bien sûr, avec gcc-5
, vous pouvez utilisez toujours la formule suivante:
#if defined (__has_include) && (__has_include(<x86intrin.h>))
#include <x86intrin.h>
#else
#error "upgrade your compiler. it's free..."
#endif
un truc sur lequel vous ne pouvez pas vraiment compter est d'utiliser les versions __GNUC__
dans clang
. La version est, pour des raisons historiques, collée à 4.2.1
. Une version qui précède l'en-tête x86intrin.h
. C'est parfois utile pour, disons, de simples extensions GNU C qui sont restées compatibles à l'envers.
-
icc : pour autant que je puisse dire, l'en-tête
x86intrin.h
est supporté depuis au moins Intel c++ 16.0. Le test de version peut être effectué avec:#if (__INTEL_COMPILER >= 1600)
. Cette version (et peut-être des versions plus anciennes) supporte également l'extension__has_include
.
-
MSVC : il apparaît que
MSVC++ 12.0 (Visual Studio 2013)
est la première version à fournirintrin.h
en - tête pasx86intrin.h
... cela suggère:#if (_MSC_VER >= 1800)
comme un test de version. Bien sûr, si vous essayez d'écrire du code qui est portable à travers tous ces compilateurs différents, le nom de l'en-tête sur cette plateforme sera le moindre de vos problèmes.