Welche Header-Dateien liefern die Grundlagen für die verschiedenen x86-SIMD-Befehlssatzerweiterungen (MMX, SSE, AVX, ...)? Es scheint unmöglich, eine solche Liste online zu finden. Korrigiere mich, wenn ich falsch liege.
quelle
Welche Header-Dateien liefern die Grundlagen für die verschiedenen x86-SIMD-Befehlssatzerweiterungen (MMX, SSE, AVX, ...)? Es scheint unmöglich, eine solche Liste online zu finden. Korrigiere mich, wenn ich falsch liege.
Heutzutage sollten Sie normalerweise nur einschließen <immintrin.h>
. Es beinhaltet alles.
GCC und clang hindern Sie daran, Intrinsics für Anweisungen zu verwenden, die Sie zum Zeitpunkt der Kompilierung nicht aktiviert haben (z. B. mit -march=native
oder -mavx2 -mbmi2 -mpopcnt -mfma -mcx16 -mtune=znver1
oder was auch immer).
Mit MSVC und ICC können Sie Intrinsics verwenden, ohne zur Kompilierungszeit etwas zu aktivieren. Sie sollten jedoch AVX aktivieren, bevor Sie AVX Intrinsics verwenden.
In der Vergangenheit (bevor immintrin.h
alles eingezogen wurde) mussten Sie manuell einen Header für die höchste gewünschte Eigenschaftsstufe einfügen.
Dies kann bei MSVC und ICC weiterhin nützlich sein, um zu verhindern, dass Sie Befehlssätze verwenden, die Sie nicht benötigen.
<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
Einschließlich eines dieser Pulls in allen vorherigen (außer AMD-only SSE4A: immintrin.h
zieht das nicht rein )
Einige Compiler haben auch <zmmintrin.h>
für AVX512.
#include <x86intrin.h>
alles in sich aufnehmen, was Sie brauchen.<zmmintrin.h>
direkt einschließen ; gcc bietet es nicht einmal an. Einfach verwenden<immintrin.h>
oder noch vollständiger<x86intrin.h>
. Diese Antwort ist grundsätzlich veraltet, es sei denn, Sie vermeiden absichtlich das Einfügen von Intrinsics für neuere Versionen von SSE, da sich Ihr Compiler nicht beschwert, wenn Sie beim Kompilieren für SSE2 eine SSE4.1-Anweisung verwenden. (gcc / Klirren Sie beklagen, so dass Sie nur für sie verwenden immintrin.h sollte IDK über andere..)Auf GCC / Clang, wenn Sie nur verwenden
Es enthält alle SSE / AVX-Header, die gemäß Compiler-Switches wie
-march=haswell
oder nur aktiviert werden-march=native
. Zusätzlich mögenbswap
oderror
werden einige x86-spezifische Anweisungen als Intrinsics verfügbar.Das MSVC-Äquivalent dieses Headers
<intrin.h>
Wenn Sie nur eine tragbare SIMD möchten, verwenden Sie
#include <immintrin.h>
MSVC, ICC und gcc / clang (und andere Compiler wie Sun, glaube ich) unterstützen diesen Header für die SIMD-Intrinsics, die von Intels einzigem Intrinsics-Finder / Suchwerkzeug dokumentiert wurden: https://software.intel.com/sites/landingpage/IntrinsicsGuide /.
quelle
<x86intrin.h>
,<intrin.h>
erzielt aber einen ähnlichen Effekt. Sie benötigen natürlich noch eine bedingte Kompilierung. :-(#include <immintrin.h>
. Verwenden Sie dies für SIMD-Intrinsics. Sie benötigen nur den noch größeren (und etwas langsamer für den Compiler)x86intrin.h
oderintrin.h
wenn Sie Dinge wie Integer-Rotation / Bit-Scan-Intrinsics benötigen (obwohl Intel einige davon alsimmintrin.h
in ihrem Intrinsics-Handbuch verfügbar dokumentiert ).x86intrin.h
/intrin.h
aber nicht in habenimmintrin.h
.Der Headername hängt von Ihrem Compiler und Ihrer Zielarchitektur ab.
intrin.h
x86intrin.h
arm_neon.h
mmintrin.h
altivec.h
spe.h
Sie können alle diese Fälle mit Anweisungen zur bedingten Vorverarbeitung behandeln:
quelle
Von dieser Seite
Im Allgemeinen können Sie also einfach
immintrin.h
alle Intel-Erweiterungenx86intrin.h
einschließen , oder wenn Sie alles möchten, einschließlich_bit_scan_forward
und_rdtsc
, sowie alle Vektor-Intrinsics enthalten nur AMD- Erweiterungen . Wenn Sie dagegen sind, mehr einzuschließen, als Sie tatsächlich benötigen, können Sie das richtige Einschließen auswählen, indem Sie sich die Tabelle ansehen.x86intrin.h
ist der empfohlene Weg, um Intrinsics für AMD XOP zu erhalten (nur Bulldozer, nicht einmal zukünftige AMD-CPUs) , anstatt einen eigenen Header zu haben.Einige Compiler generieren weiterhin Fehlermeldungen, wenn Sie Intrinsics für Befehlssätze verwenden, die Sie nicht aktiviert haben (z. B.
_mm_fmadd_ps
ohne fma zu aktivieren, selbst wenn Sieimmintrin.h
AVX2 einschließen und aktivieren).quelle
smmintrin
(SSE4.1) ist Penryn (45 nm Core2), nicht Nehalem ("i7"). Können wir aufhören, "i7" als Architekturnamen zu verwenden? Es ist jetzt bedeutungslos, dass Intel es weiterhin für die SnB-Familie verwendet .immintrin.h
scheint keine Intrinsics in GCC 9.1.0 zu enthalten_popcnt32
und_popcnt64
(nicht zu verwechseln mit denen inpopcntintrin.h
!). Es scheint alsox86intrin.h
immer noch einen Zweck zu erfüllen.Wie in vielen Antworten und Kommentaren angegeben,
<x86intrin.h>
handelt es sich um den umfassenden Header für x86 [-64] SIMD-Intrinsics. Es enthält auch intrinsische unterstützende Anweisungen für andere ISA-Erweiterungen.gcc
,,clang
undicc
haben sich alle darauf geeinigt. Ich musste ein wenig nach Versionen suchen, die den Header unterstützen, und dachte, es könnte nützlich sein, einige Ergebnisse aufzulisten ...gcc : Unterstützung für
x86intrin.h
first erscheint ingcc-4.5.0
. Diegcc-4
Release-Serie wird nicht mehr beibehalten, währendgcc-6.x
es sich um die aktuelle stabile Release-Serie handelt.gcc-5
Außerdem wurde die__has_include
in allenclang-3.x
Releases vorhandene Erweiterung eingeführt .gcc-7
befindet sich in der Vorabversion (Regressionstests usw.) und wird nach dem aktuellen Versionsschema als veröffentlichtgcc-7.1.0
.clang :
x86intrin.h
scheint für alleclang-3.x
Releases unterstützt worden zu sein . Die neueste stabile Version istclang (LLVM) 3.9.1
. Der Entwicklungszweig istclang (LLVM) 5.0.0
. Es ist nicht klar, was mit der4.x
Serie passiert ist .Apple klirrt : Ärgerlicherweise entspricht die Versionierung von Apple nicht der der
LLVM
Projekte. Das heißt, die aktuelle Version:clang-800.0.42.1
basiert aufLLVM 3.9.0
. Die ersteLLVM 3.0
basierte Version scheintApple clang 2.1
wieder in zu seinXcode 4.1
.LLVM 3.1
erscheint zuerst mitApple clang 3.1
(einem numerischen Zufall) inXcode 4.3.3
.Apple definiert auch
__apple_build_version__
zB8000042
. Dies scheint das stabilste, streng aufsteigende verfügbare Versionsschema zu sein. Wenn Sie ältere Compiler nicht unterstützen möchten, müssen Sie einen dieser Werte als Mindestanforderung festlegen.Jede neuere Version von
clang
, einschließlich Apple-Versionen, sollte daher kein Problem habenx86intrin.h
. Natürlich können Sie zusammen mitgcc-5
immer Folgendes verwenden:Ein Trick, auf den Sie sich nicht wirklich verlassen können, ist die Verwendung der
__GNUC__
Versionen inclang
. Die Versionierung bleibt aus historischen Gründen hängen4.2.1
. Eine Version vor demx86intrin.h
Header. Dies ist gelegentlich nützlich, beispielsweise für einfache GNU C-Erweiterungen, die abwärtskompatibel geblieben sind.icc : Soweit ich das beurteilen kann, wird der
x86intrin.h
Header seit mindestens Intel C ++ 16.0 unterstützt. Der Versionstest kann durchgeführt werden mit :#if (__INTEL_COMPILER >= 1600)
. Diese Version (und möglicherweise frühere Versionen) bietet auch Unterstützung für die__has_include
Erweiterung.MSVC : Es scheint, dass dies
MSVC++ 12.0 (Visual Studio 2013)
die erste Version ist, die denintrin.h
Header bereitstellt - nichtx86intrin.h
... dies legt nahe:#if (_MSC_VER >= 1800)
als Versionstest. Wenn Sie versuchen, Code zu schreiben, der auf all diese verschiedenen Compiler portierbar ist, ist der Headername auf dieser Plattform natürlich das geringste Ihrer Probleme.quelle