web-dev-qa-db-de.com

Header-Dateien für x86-SIMD-Intrinsics

Welche Header-Dateien enthalten die eigentlichen Informationen 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.

119
fredoverflow
<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
155
fredoverflow

Wenn Sie gerade verwenden

#include <x86intrin.h>

es enthält alle SSE/AVX-Header, die gemäß Compiler-Optionen wie -march=corei7 oder nur -march=native aktiviert sind. Zusätzlich werden einige x86-spezifische Anweisungen wie bswap oder ror als Intrinsics verfügbar.

71
Gunther Piez

Der Headername hängt von Ihrem Compiler und Ihrer Zielarchitektur ab.

  • Verwenden Sie für Microsoft C++ (für x86, x86-64 oder ARM) und Intel C/C++ Compiler für Windows intrin.h
  • Verwenden Sie für gcc/clang/icc-Targeting x86/x86-64 x86intrin.h
  • Für gcc/clang/armcc-Targeting ARM mit NEON benutze arm_neon.h
  • Für gcc/clang/armcc-Targeting ARM mit WMMX verwenden Sie mmintrin.h
  • Für gcc/clang/xlcc-Targeting von PowerPC mit VMX (aka Altivec) und/oder VSX verwenden Sie altivec.h
  • Für gcc/clang-Targeting von PowerPC mit SPE verwenden Sie spe.h

Sie können all diese Fälle mit bedingten Vorverarbeitungs-Direktiven behandeln:

#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
55
Marat Dukhan

Von diesem Seite

+----------------+------------------------------------------------------------------------------------------+
|     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             |
+----------------+------------------------------------------------------------------------------------------+

Im Allgemeinen können Sie also einfach immintrin.h, um alle Intel-Erweiterungen abzurufen, oder x86intrin.h wenn du alles willst, auch _bit_scan_forward und _rdtsc sowie alle Vektor-Intrinsics enthalten nur AMD. Wenn Sie dagegen sind, mehr aufzunehmen, als Sie tatsächlich brauchen, können Sie das richtige Include auswählen, indem Sie sich die Tabelle ansehen.

x86intrin.h ist die empfohlene Methode, um Intrinsics für AMD XOP (Bulldozer-only, nicht einmal zukünftige AMD-CPUs) abzurufen, anstatt einen eigenen Header zu haben.

Einige Compiler erzeugen weiterhin Fehlermeldungen, wenn Sie Intrinsics für nicht aktivierte Anweisungssätze verwenden (z. B. _mm_fmadd_ps ohne fma zu aktivieren, auch wenn Sie immintrin.h und aktivieren Sie AVX2).

39
ecerulm

Wie in vielen Antworten und Kommentaren angegeben, ist <x86intrin.h>der umfassende Header für x86 [-64] SIMD-Eigenheiten. Es enthält auch grundlegende Anweisungen für die Unterstützung anderer ISA Erweiterungen. gcc, clang und icc Finden Sie heraus, welche Versionen den Header unterstützen, und halten Sie es für nützlich, einige Ergebnisse aufzulisten ...

  • gcc: Unterstützung für x86intrin.h erscheint zuerst in gcc-4.5.0. Die Release-Reihe gcc-4 Wird nicht mehr gepflegt, während gcc-6.x Die aktuelle stabile Release-Reihe ist. gcc-5 Führte auch die in allen __has_include - Releases vorhandene Erweiterung clang-3.x Ein. gcc-7 Befindet sich in der Vorabversion (Regressionstests usw.) und wird nach dem aktuellen Versionsschema als gcc-7.1.0 Veröffentlicht.

  • clang: x86intrin.h wurde anscheinend für alle clang-3.x - Releases unterstützt. Die neueste stabile Version ist clang (LLVM) 3.9.1. Der Entwicklungszweig ist clang (LLVM) 5.0.0. Es ist nicht klar, was mit der 4.x - Serie passiert ist.

  • Apple klappert: Leider stimmt die Versionierung von Apple nicht mit der der LLVM -Projekte überein. Das heißt, die aktuelle Version clang-800.0.42.1 Basiert auf LLVM 3.9.0. Die erste auf LLVM 3.0 Basierende Version scheint Apple clang 2.1 In Xcode 4.1 Zu sein. LLVM 3.1 Erscheint zuerst mit Apple clang 3.1 (Ein numerischer Zufall) in Xcode 4.3.3.

    Apple definiert auch __Apple_build_version__, Z. B. 8000042. Dies scheint das stabilste, streng aufsteigende Versionierungsschema zu sein, das es gibt. Wenn Sie keine älteren Compiler 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 mit x86intrin.h Haben. Natürlich zusammen mit gcc-5 kann immer Folgendes verwenden:

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

Ein Trick, auf den Sie sich nicht wirklich verlassen können, ist die Verwendung der __GNUC__ - Versionen in clang. Die Versionierung bleibt aus historischen Gründen bei 4.2.1. Eine Version vor dem Header x86intrin.h. Es ist gelegentlich nützlich 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 Erweiterung __has_include.

  • MSVC : Es scheint, dass MSVC++ 12.0 (Visual Studio 2013) die erste Version ist, die den Header intrin.h liefert - not x86intrin.h ... dies schlägt vor: #if (_MSC_VER >= 1800) als ein Versionstest. Wenn Sie versuchen, Code zu schreiben, der auf all diese verschiedenen Compiler übertragbar ist, ist der Headername auf dieser Plattform das geringste Problem.

11
Brett Hale