File header mana yang menyediakan intrinsik untuk ekstensi set instruksi x86 SIMD yang berbeda (MMX, SSE, AVX, ...)? Tampaknya tidak mungkin menemukan daftar online seperti itu. Koreksi saya jika saya salah.
File header mana yang menyediakan intrinsik untuk ekstensi set instruksi x86 SIMD yang berbeda (MMX, SSE, AVX, ...)? Tampaknya tidak mungkin menemukan daftar online seperti itu. Koreksi saya jika saya salah.
Jawaban:
Hari-hari ini Anda biasanya hanya perlu memasukkan <immintrin.h>. Itu termasuk semuanya.
GCC dan dentang akan menghentikan Anda dari menggunakan intrinsik untuk instruksi yang belum Anda aktifkan pada waktu kompilasi (misalnya dengan -march=nativeatau -mavx2 -mbmi2 -mpopcnt -mfma -mcx16 -mtune=znver1atau apa pun.)
MSVC dan ICC akan memungkinkan Anda menggunakan intrinsik tanpa mengaktifkan apa pun pada waktu kompilasi, tetapi Anda tetap harus mengaktifkan AVX sebelum menggunakan AVX intrinsics.
Secara historis (sebelum immintrin.hmenarik semuanya) Anda harus memasukkan header secara manual untuk level intrinsik tertinggi yang Anda inginkan.
Ini mungkin masih berguna dengan MSVC dan ICC untuk menghentikan diri Anda dari menggunakan set instruksi yang tidak Anda inginkan.
<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
Termasuk salah satu dari tarikan ini di semua yang sebelumnya (kecuali SSE4A khusus AMD: immintrin.htidak menarik itu)
Beberapa kompiler juga ada <zmmintrin.h>untuk AVX512.
<zmmintrin.h>secara langsung; gcc bahkan tidak menyediakannya. Cukup gunakan<immintrin.h> atau bahkan lebih lengkap <x86intrin.h>. Jawaban ini pada dasarnya sudah usang, kecuali jika Anda secara sengaja menghindari memasukkan intrinsik untuk versi SSE yang lebih baru karena kompiler Anda tidak mengeluh ketika Anda menggunakan instruksi SSE4.1 saat menyusun untuk SSE2. (Gcc / dentang memang mengeluh, jadi Anda harus menggunakan immintrin.h untuk mereka. IDK tentang orang lain.)
Pada GCC / dentang, jika Anda gunakan saja
#include <x86intrin.h>
itu akan mencakup semua header SSE / AVX yang diaktifkan sesuai dengan sakelar kompiler suka -march=haswellatau adil -march=native. Selain itu beberapa instruksi spesifik x86 suka bswapatau rortersedia sebagai intrinsik.
Setara MSVC dari header ini <intrin.h>
Jika Anda hanya ingin SIMD portabel, gunakan #include <immintrin.h>
MSVC, ICC, dan gcc / dentang (dan kompiler lain seperti Sun, saya pikir) semuanya mendukung tajuk ini untuk intrinsik SIMD yang didokumentasikan oleh satu-satunya alat pencari / penelusuran intrinsik Intel: https://software.intel.com/sites/landingpage/IntrinsicsGuide /
<x86intrin.h>, tetapi <intrin.h>mencapai efek yang serupa. Anda masih membutuhkan kompilasi bersyarat, tentu saja. :-(
#include <immintrin.h>. Gunakan itu untuk SIMD intrinsik. Anda hanya memerlukan kompiler yang bahkan lebih besar (dan sedikit lebih lambat) x86intrin.hatau intrin.hjika Anda memerlukan hal-hal seperti integer rotate / bit-scan intrinsik (walaupun Intel mendokumentasikan beberapa dari mereka yang tersedia di immintrin.h dalam panduan intrinsik mereka ).
x86intrin.h/ intrin.htetapi tidak di immintrin.h.
Nama header tergantung pada kompiler dan arsitektur target Anda.
intrin.hx86intrin.harm_neon.hmmintrin.haltivec.hspe.hAnda dapat menangani semua kasus ini dengan arahan preprocessing bersyarat:
#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
Dari halaman ini
+----------------+------------------------------------------------------------------------------------------+
| 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 |
+----------------+------------------------------------------------------------------------------------------+
Jadi secara umum Anda bisa memasukkan immintrin.huntuk mendapatkan semua ekstensi Intel, atau x86intrin.hjika Anda menginginkan semuanya, termasuk _bit_scan_forwarddan _rdtsc, serta semua vektor intrinsik termasuk yang hanya AMD. Jika Anda menentang memasukkan lebih banyak yang sebenarnya Anda butuhkan, maka Anda dapat memilih yang benar termasuk dengan melihat tabel.
x86intrin.hadalah cara yang disarankan untuk mendapatkan intrinsik untuk AMD XOP (hanya Bulldozer, bahkan untuk CPU AMD yang akan datang) , daripada memiliki header sendiri.
Beberapa kompiler masih akan menghasilkan pesan kesalahan jika Anda menggunakan intrinsik untuk set instruksi yang belum Anda aktifkan (mis. _mm_fmadd_psTanpa mengaktifkan fma, bahkan jika Anda memasukkan immintrin.hdan mengaktifkan AVX2).
smmintrin(SSE4.1) adalah Penryn (45nm Core2), bukan Nehalem ("i7"). Bisakah kita berhenti menggunakan "i7" sebagai nama arsitektur? Tidak ada artinya sekarang karena Intel terus menggunakannya untuk keluarga SnB .
immintrin.htampaknya tidak termasuk _popcnt32dan _popcnt64(jangan disamakan dengan yang ada di popcntintrin.hdalamnya!) intrinsik pada GCC 9.1.0. Jadi tampaknya x86intrin.hmasih memiliki tujuan.
Seperti banyak dari jawaban dan komentar telah menyatakan, <x86intrin.h>adalah yang sundulan komprehensif untuk x86 [-64] SIMD intrinsik. Ini juga menyediakan instruksi pendukung intrinsik untuk ekstensi ISA lainnya. gcc,, clangdan iccsemuanya sudah sepakat. Saya perlu melakukan penggalian pada versi yang mendukung tajuk, dan saya pikir mungkin berguna untuk membuat daftar beberapa temuan ...
gcc : dukungan untuk x86intrin.hpertama kali muncul di gcc-4.5.0. The gcc-4seri rilis tidak lagi dipertahankan, sedangkan gcc-6.xadalah saat rilis stabil seri. gcc-5juga memperkenalkan __has_includehadiah ekstensi di semua clang-3.xrilis. gcc-7dalam pra-rilis (pengujian regresi, dll.) dan mengikuti skema versi saat ini, akan dirilis sebagai gcc-7.1.0.
dentang : x86intrin.htampaknya telah didukung untuk semua clang-3.xrilis. Rilis stabil terbaru adalah clang (LLVM) 3.9.1. Cabang pengembangan adalah clang (LLVM) 5.0.0. Tidak jelas apa yang terjadi pada 4.xseri ini.
Dentang Apple : mengganggu, versi Apple tidak sesuai dengan LLVMproyek. Yang mengatakan, rilis saat ini:, clang-800.0.42.1didasarkan pada LLVM 3.9.0. Versi LLVM 3.0berbasis pertama tampaknya Apple clang 2.1kembali Xcode 4.1. LLVM 3.1pertama kali muncul dengan Apple clang 3.1(kebetulan numerik) di Xcode 4.3.3.
Apple juga mendefinisikan __apple_build_version__misalnya 8000042,. Tampaknya ini tentang skema versi yang paling stabil dan ketat yang tersedia. Jika Anda tidak ingin mendukung kompiler lawas, jadikan salah satu dari nilai ini persyaratan minimum.
clangOleh karena itu, setiap versi terbaru , termasuk versi Apple, tidak akan memiliki masalah dengan x86intrin.h. Tentu saja, bersama dengan gcc-5, Anda selalu dapat menggunakan yang berikut:
#if defined (__has_include) && (__has_include(<x86intrin.h>))
#include <x86intrin.h>
#else
#error "upgrade your compiler. it's free..."
#endif
Satu trik yang tidak bisa Anda andalkan adalah menggunakan __GNUC__versi di clang. Versi ini, karena alasan historis, terjebak di 4.2.1. Versi yang mendahului x86intrin.hheader. Ini kadang-kadang berguna untuk, katakanlah, ekstensi GNU C sederhana yang tetap kompatibel ke belakang.
icc : sejauh yang saya tahu, x86intrin.hheader didukung sejak setidaknya Intel C ++ 16.0. Tes Versi oleh dapat dilakukan dengan: #if (__INTEL_COMPILER >= 1600). Versi ini (dan mungkin versi sebelumnya) juga memberikan dukungan untuk __has_includeekstensi.
MSVC : Tampaknya MSVC++ 12.0 (Visual Studio 2013)ini adalah versi pertama yang menyediakan intrin.hheader - bukan x86intrin.h ... ini menyarankan: #if (_MSC_VER >= 1800)sebagai tes versi. Tentu saja, jika Anda mencoba untuk menulis kode yang portabel di semua kompiler berbeda ini, nama header pada platform ini akan menjadi yang paling sedikit masalah Anda.
#include <x86intrin.h>yang menarik semua yang Anda butuhkan.