X86 SIMD intrinsics için başlık dosyaları


131

Hangi başlık dosyaları farklı x86 SIMD komut seti uzantıları (MMX, SSE, AVX, ...) için içsel bilgiler sağlar? İnternette böyle bir liste bulmak imkansız görünüyor. Yanlışsam düzelt.

Yanıtlar:


174

Bu günlerde normalde sadece eklemelisiniz <immintrin.h>. Her şeyi içerir.

GCC, clang talimatlar için derleme zamanında etkinleştirmediğinizden intrinsics kullanmayasın (örneğin ile -march=nativeveya -mavx2 -mbmi2 -mpopcnt -mfma -mcx16 -mtune=znver1ya da her neyse.)

MSVC ve ICC, derleme zamanında hiçbir şeyi etkinleştirmeden içsel bilgileri kullanmanıza izin verir, ancak yine de AVX intrinsiklerini kullanmadan önce AVX'i etkinleştirmelisiniz.


Tarihsel olarak ( immintrin.hher şeyi içeri çekmeden önce ), istediğiniz en yüksek iç bilgiler için manuel olarak bir başlık eklemeniz gerekiyordu.

Bu, MSVC ve ICC'de, gerek duymak istemediğiniz komut setlerini kullanmaktan kendinizi alıkoymak için hala yararlı olabilir.

<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

Tüm öncekilere bu çekimlerden biri dahil (yalnızca AMD için SSE4A hariç: immintrin.hbunu içeri çekmiyor)

Bazı derleyicilerin <zmmintrin.h>AVX512 için de vardır .


62
Ya da #include <x86intrin.h>ihtiyacınız olan her şeyi çekebilirsiniz .
Paul R.

2
zmmintrin.h, AVX-512 özüne sahiptir.
2014

3
SSE3 / SSSE3 / SSE4.1 ve 4.2 için neden p, t, s ve n var? Bu karakterler neyi temsil ediyor?
phuclv

5
@ LưuVĩnhPhúc SSE3 = Yeni talimatları önceden kaydedin, SSSE3 = Tejas yeni talimatları. Sanırım SSE4.2 ve AES, tanıtıldıkları işlemci ailesini ifade ediyor (Nehalem ve Westmere)
Drew McGowen

14
<zmmintrin.h>Doğrudan dahil etmeyin ; gcc bunu bile sağlamaz. Sadece<immintrin.h> veya daha eksiksiz olanı kullanın<x86intrin.h> . Bu yanıt, SSE'nin daha yeni sürümleri için iç bilgi eklemekten kasıtlı olarak kaçınmadığınız sürece, temelde geçersizdir, çünkü derleyiciniz SSE2 için derleme yaparken bir SSE4.1 talimatı kullandığınızda şikayet etmez. (gcc / çınlama yok . Sadece onlar için immintrin.h kullanmalıdır nedenle, şikayet başkaları hakkında IDK.)
Peter Cordes

76

GCC / clang'da, yalnızca

#include <x86intrin.h>

gibi -march=haswellveya sadece derleyici anahtarlarına göre etkinleştirilen tüm SSE / AVX başlıklarını içerecektir -march=native. Ek olarak, bazı x86'ya özgü talimatlar bswapveya roriçsel olarak kullanılabilir hale gelir.


Bu başlığın MSVC eşdeğeri <intrin.h>


Yalnızca taşınabilir SIMD istiyorsanız, #include <immintrin.h>

MSVC, ICC ve gcc / clang (ve sanırım Sun gibi diğer derleyiciler), Intel'in tek dahili bulucu / arama aracı tarafından belgelenen SIMD içsel bilgileri için bu başlığı destekler: https://software.intel.com/sites/landingpage/IntrinsicsGuide /


Daha yeni sürümlerin olabileceğinden emin değildim ... Her neyse, gcc, icc ve clang'a sahip olduğu sürece kullanmamda bir
sakınca yok

5
MSVC'de yoktur <x86intrin.h>, ancak <intrin.h>benzer bir etki yaratır. Elbette hala koşullu derlemeye ihtiyacınız var. :-(
Cody Gray

Tüm büyük x86 derleyicilerinde #include <immintrin.h>. SIMD içselleri için bunu kullanın. Yalnızca daha büyük olana (ve derleyiciye biraz daha yavaş) ihtiyacınız varsa x86intrin.hveya intrin.htamsayı döndürme / bit tarama içselleri gibi şeylere ihtiyacınız varsa (Intel bunlardan bazılarını immintrin.h içsel kılavuzunda mevcut olarak belgelese de ).
Peter Cordes

IIRC, bazı olmayan SIMD intrinsics immintrin.h varlık olarak Intel belgeler ancak gcc, clang ve / veya MSVC sadece sahip bulunmaktadır x86intrin.h/ intrin.hama değil de immintrin.h.
Peter Cordes

56

Başlık adı, derleyicinize ve hedef mimarinize bağlıdır.

  • Microsoft C ++ (x86, x86-64 veya ARM hedeflenir) ve Windows kullanımı için Intel C / C ++ Derleyici için intrin.h
  • Gcc / clang / icc hedefleme x86 / x86-64 için kullanın x86intrin.h
  • NEON kullanımlı gcc / clang / armcc hedefleme ARM için arm_neon.h
  • WMMX kullanımıyla gcc / clang / armcc hedefleme ARM için mmintrin.h
  • VMX (diğer adıyla Altivec) ve / veya VSX kullanımı ile PowerPC'yi hedefleyen gcc / clang / xlcc için altivec.h
  • SPE kullanımıyla PowerPC'yi hedefleyen gcc / clang için spe.h

Tüm bu durumları koşullu ön işleme yönergeleriyle halledebilirsiniz:

#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

Listenize ekleyebileceğiniz birkaç tane daha: gcc ile UltraSPARC + VIS üzerinde visintrin.h kullanın; Sun'ın VSDK'sına sahipseniz, vis.h farklı bir iç özellikler kümesi sunar. Belgeler burada bulunabilir: GCC VIS yerleşikleri , Sun VIS kullanım kılavuzu .
onitake

44

Bu sayfadan

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

Dolayısıyla, genel olarak, immintrin.htüm Intel uzantılarını almak için dahil edebilirsiniz veya ve x86intrin.hdahil olmak üzere her şeyi istiyorsanız, tüm vektör içselleri yalnızca AMD olanları içerir. Gerçekte ihtiyacınız olandan daha fazlasını dahil etmeye karşıysanız, tabloya bakarak doğru dahil etmeyi seçebilirsiniz._bit_scan_forward_rdtsc

x86intrin.hkendi başlığına sahip olmak yerine AMD XOP için (yalnızca Buldozer, hatta gelecekteki AMD CPU'lar değil ) içsel bilgiler edinmenin önerilen yoludur .

Etkinleştirmediğiniz komut kümeleri için içsel kullanırsanız (örneğin _mm_fmadd_ps, AVX2'yi dahil immintrin.hetseniz ve etkinleştirseniz bile fma'yı etkinleştirmeden) bazı derleyiciler yine de hata mesajları üretecektir .


1
smmintrin(SSE4.1) Penryn'dir (45nm Çekirdek2), Nehalem ("i7") değil. Mimari adı olarak "i7" yi kullanmayı bırakabilir miyiz? Intel'in SnB ailesi için kullanmaya devam etmesi artık anlamsız .
Peter Cordes

immintrin.hGCC 9.1.0'da içsel bilgiler içermiyor _popcnt32ve _popcnt64(içindekilerle karıştırılmayacak popcntintrin.h!) görünmüyor . Yani x86intrin.hhala bir amaca hizmet ediyor gibi görünüyor .
Thom Wiggers

12

Cevaplar ve yorumlar birçok belirttiğimiz gibi, <x86intrin.h>olduğu x86 [-64] SIMD intrinsics için kapsamlı başlığı. Ayrıca, diğer ISA uzantıları için içsel destekleyici talimatlar sağlar. , ve hepsi bu konuda kararlaştırdı. Başlığı destekleyen sürümlerde biraz araştırma yapmam gerekiyordu ve bazı bulguları listelemenin faydalı olabileceğini düşündüm ...gccclangicc

  • gcc : x86intrin.hilk için destek içinde görünür gcc-4.5.0. gcc-4Salma serisi artık ise, muhafaza ediliyor gcc-6.xolup , mevcut kararlı açma dizisi. gcc-5ayrıca __has_includetüm clang-3.xsürümlerde bulunan uzantıyı tanıttı . gcc-7ön sürümde (regresyon testi, vb.) ve mevcut sürüm oluşturma şemasını takiben, olarak yayınlanacaktır gcc-7.1.0.

  • clang : x86intrin.htüm clang-3.xsürümler için desteklendiği görülüyor . En son kararlı sürüm clang (LLVM) 3.9.1. Geliştirme dalı clang (LLVM) 5.0.0. Diziye ne olduğu net değil 4.x.

  • Apple clang : can sıkıcı bir şekilde, Apple'ın sürüm belirlemesi LLVMprojelerinkiyle uyuşmuyor . Bununla birlikte, mevcut sürüm: clang-800.0.42.1dayanmaktadır LLVM 3.9.0. İlk LLVM 3.0tabanlı sürüm Apple clang 2.1geri dönüyor gibi görünüyor Xcode 4.1. LLVM 3.1ilk olarak içinde Apple clang 3.1(sayısal bir tesadüf) ile görünür Xcode 4.3.3.

    Apple ayrıca __apple_build_version__örneğin, tanımlar 8000042. Bu, mevcut en kararlı, kesinlikle artan sürüm oluşturma şeması gibi görünüyor. Eski derleyicileri desteklemek istemiyorsanız, bu değerlerden birini minimum gereksinim yapın.

Bu clangnedenle, Apple sürümleri de dahil olmak üzere son sürümlerin herhangi bir sorunu olmamalıdır x86intrin.h. Tabii ki, aşağıdakilerle birlikte gcc-5her zaman kullanabilirsiniz:

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

Gerçekten güvenemeyeceğiniz bir numara, içindeki __GNUC__sürümleri kullanmaktır clang. Versiyonlama, tarihsel nedenlerden dolayı, takılıp kalmıştır 4.2.1. Başlıktan önce gelen bir sürüm x86intrin.h. Zaman zaman, örneğin geriye doğru uyumlu kalan basit GNU C uzantıları için yararlıdır.

  • icc : Anladığım kadarıyla x86intrin.hbaşlık en azından Intel C ++ 16.0'dan beri destekleniyor. Sürüm testinde tarafından gerçekleştirilen edebilirsiniz: #if (__INTEL_COMPILER >= 1600). Bu sürüm (ve muhtemelen daha önceki sürümler) ayrıca __has_includeuzantı için destek sağlar .

  • MSVC : Görünüşe göre MSVC++ 12.0 (Visual Studio 2013)bu intrin.hbaşlık sağlayan ilk sürüm - değil x86intrin.h ... bu şunu öneriyor: #if (_MSC_VER >= 1800)bir sürüm testi olarak. Elbette, tüm bu farklı derleyiciler arasında taşınabilir bir kod yazmaya çalışıyorsanız, bu platformdaki başlık adı sorunlarınızın en küçüğü olacaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.