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.
la source
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.
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=native
ou-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.h
de 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.h
ne tire pas cela)
Certains compilateurs ont également <zmmintrin.h>
pour AVX512.
#include <x86intrin.h>
ce qui rassemble tout ce dont vous avez besoin.<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..)Sur GCC / clang, si vous utilisez uniquement
il inclura tous les en-têtes SSE / AVX qui sont activés selon les commutateurs du compilateur comme
-march=haswell
ou juste-march=native
. De plus, certaines instructions spécifiques à x86 aimentbswap
ouror
deviennent 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 /
la source
<x86intrin.h>
, mais<intrin.h>
réalise un effet similaire. Vous avez toujours besoin d'une compilation conditionnelle, bien sûr. :-(#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.h
ouintrin.h
si 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 disponiblesimmintrin.h
dans leur guide des intrinsèques ).x86intrin.h
/intrin.h
mais pas dansimmintrin.h
.Le nom de l'en-tête dépend de votre compilateur et de l'architecture cible.
intrin.h
x86intrin.h
arm_neon.h
mmintrin.h
altivec.h
spe.h
Vous pouvez gérer tous ces cas avec des directives de prétraitement conditionnel:
la source
De cette page
Donc, en général, vous pouvez simplement inclure
immintrin.h
pour obtenir toutes les extensions Intel, oux86intrin.h
si 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_ps
sans activer fma, même si vous incluezimmintrin.h
et activez AVX2).la source
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 .immintrin.h
ne semble pas inclure_popcnt32
et_popcnt64
(à ne pas confondre avec ceux depopcntintrin.h
!) intrinsèques sur GCC 9.1.0. Il semble donc que celax86intrin.h
sert toujours un objectif.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
,,clang
eticc
ont 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.h
apparaît en premier dansgcc-4.5.0
. Lagcc-4
série de versions n'est plus maintenue, tandis quegcc-6.x
la série de versions stables actuelle .gcc-5
a également introduit l'__has_include
extension présente dans toutes lesclang-3.x
versions.gcc-7
est en pré-version (test de régression, etc.) et suivant le schéma de version actuel, sera publié sous la formegcc-7.1.0
.clang :
x86intrin.h
semble avoir été pris en charge pour toutes lesclang-3.x
versions. La dernière version stable estclang (LLVM) 3.9.1
. La branche de développement estclang (LLVM) 5.0.0
. On ne sait pas ce qui est arrivé à la4.x
série.Apple retentit : ennuyeux, le versionnage d'Apple ne correspond pas à celui des
LLVM
projets. Cela dit, la version actuelle:,clang-800.0.42.1
est basée surLLVM 3.9.0
. La premièreLLVM 3.0
version basée semble être deApple clang 2.1
retourXcode 4.1
.LLVM 3.1
apparaît d'abord avecApple clang 3.1
(une coïncidence numérique) dansXcode 4.3.3
.Apple définit également
__apple_build_version__
par exemple8000042
. 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 avecx86intrin.h
. Bien sûr,gcc-5
vous pouvez toujours utiliser les éléments suivants:Une astuce sur laquelle vous ne pouvez pas vraiment compter consiste à utiliser les
__GNUC__
versions dansclang
. La gestion des versions est, pour des raisons historiques, bloquée4.2.1
. Une version qui précède l'en-x86intrin.h
tê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.h
tê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_include
extension.MSVC : Il semble que ce
MSVC++ 12.0 (Visual Studio 2013)
soit la première version à fournir l'en-intrin.h
tête - pasx86intrin.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.la source