que etiquetas etiqueta encabezado definicion x86 header-files sse simd intrinsics

etiquetas - Archivos de encabezado para x86 SIMD intrinsics



que es h2 en html (5)

¿Qué archivos de cabecera proporcionan las características intrínsecas de las diferentes extensiones de conjunto de instrucciones x86 SIMD (MMX, SSE, AVX, ...)? Parece imposible encontrar una lista en línea. Corrígeme si estoy equivocado.


Como muchas de las respuestas y comentarios han indicado, <x86intrin.h> es el encabezado completo para x86 [-64] intrínsecos SIMD. También proporciona instrucciones de soporte intrínsecas para otras extensiones de ISA. gcc , clang e icc han decidido por esto. Necesitaba investigar en las versiones que admiten el encabezado, y pensé que sería útil enumerar algunos hallazgos ...

  • gcc : la compatibilidad con x86intrin.h aparece por primera vez en gcc-4.5.0 . La serie de lanzamiento de gcc-4 ya no se mantiene, mientras que gcc-6.x es la serie de lanzamiento estable actual . gcc-5 también introdujo la extensión __has_include presente en todas clang-3.x versiones de clang-3.x . gcc-7 está en prelanzamiento (pruebas de regresión, etc.) y siguiendo el esquema de control de versiones actual, se lanzará como gcc-7.1.0 .

  • clang : Parece que x86intrin.h fue compatible con todas clang-3.x versiones de clang-3.x . La última versión estable es clang (LLVM) 3.9.1 . La rama de desarrollo es clang (LLVM) 5.0.0 . No está claro qué pasó con la serie 4.x

  • Choque de Apple : molestamente, el control de versiones de Apple no se corresponde con el de los proyectos de LLVM . Dicho esto, la versión actual: clang-800.0.42.1 , se basa en LLVM 3.9.0 . La primera versión basada en LLVM 3.0 parece ser Apple clang 2.1 en Xcode 4.1 . LLVM 3.1 aparece por primera vez con Apple clang 3.1 (una coincidencia numérica) en Xcode 4.3.3 .

    Apple también define __apple_build_version__ por ejemplo, 8000042 . Esto parece ser el esquema de control de versiones más estable y estrictamente ascendente disponible. Si no desea admitir compiladores heredados, haga que uno de estos valores sea un requisito mínimo.

Cualquier versión reciente de clang , incluidas las versiones de Apple, no debería tener problemas con x86intrin.h . Por supuesto, junto con gcc-5 , siempre puedes usar lo siguiente:

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

Un truco en el que no puedes confiar es usar las versiones de __GNUC__ en clang . El control de versiones está, por razones históricas, estancado en 4.2.1 . Una versión que precede al encabezado x86intrin.h En ocasiones es útil para, por ejemplo, extensiones simples de GNU C que han permanecido compatibles con versiones anteriores.

  • icc : por lo que puedo decir, el encabezado x86intrin.h es compatible, al menos, con Intel C ++ 16.0. La prueba de versión se puede realizar con: #if (__INTEL_COMPILER >= 1600) . Esta versión (y posiblemente versiones anteriores) también brinda soporte para la extensión __has_include .

  • MSVC : parece que MSVC++ 12.0 (Visual Studio 2013) es la primera versión que proporciona el encabezado intrin.h , no x86intrin.h ... esto sugiere: #if (_MSC_VER >= 1800) como prueba de versión. Por supuesto, si intenta escribir código que sea portátil en todos estos compiladores diferentes, el nombre de encabezado en esta plataforma será el menor de sus problemas.


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

Entonces, en general, puede incluir immintrin.h para obtener todas las extensiones de Intel, o x86intrin.h si desea que todo, incluidos _bit_scan_forward y _rdtsc , así como todos los vectores intrínsecos, incluyan solo los de AMD. Si está en contra de incluir más de lo que realmente necesita, puede elegir incluir el derecho mirando la tabla.

x86intrin.h es la forma recomendada de obtener intrínsecos para AMD XOP (solo Bulldozer, ni siquiera futuras CPU AMD) , en lugar de tener su propio encabezado.

Algunos compiladores seguirán generando mensajes de error si utiliza intrínsecos para los conjuntos de instrucciones que no ha activado (por ejemplo, _mm_fmadd_ps sin habilitar fma, incluso si incluye immintrin.h y habilita AVX2).


El nombre del encabezado depende de su compilador y arquitectura de destino.

  • Para Microsoft C ++ (dirigida a x86, x86-64 o ARM) y el compilador Intel C / C ++ para Windows, use intrin.h
  • Para la orientación gcc / clang / icc x86 / x86-64 use x86intrin.h
  • Para gcc / clang / brazocc, el ARM con NEON usa arm_neon.h
  • Para gcc / clang / armcc target ARM con WMMX use mmintrin.h
  • Para gcc / clang / xlcc que apunta a PowerPC con VMX (también conocido como Altivec) y / o VSX use altivec.h
  • Para la segmentación gcc / clang PowerPC con SPE use spe.h

Puede manejar todos estos casos con directivas de preprocesamiento condicional:

#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


Si usa solo

#include <x86intrin.h>

incluirá todos los encabezados SSE / AVX que están habilitados de acuerdo con los modificadores del compilador como -march=corei7 o simplemente -march=native . Además, algunas instrucciones específicas de x86 como bswap o ror están disponibles como intrínsecas.


<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