Które pliki nagłówkowe zawierają elementy wewnętrzne dla różnych rozszerzeń zestawu instrukcji x86 SIMD (MMX, SSE, AVX, ...)? Znalezienie takiej listy w Internecie wydaje się niemożliwe. Popraw mnie, jeśli się mylę.
źródło
Które pliki nagłówkowe zawierają elementy wewnętrzne dla różnych rozszerzeń zestawu instrukcji x86 SIMD (MMX, SSE, AVX, ...)? Znalezienie takiej listy w Internecie wydaje się niemożliwe. Popraw mnie, jeśli się mylę.
W dzisiejszych czasach zwykle należy po prostu uwzględnić <immintrin.h>
. Zawiera wszystko.
GCC i brzęk zatrzyma cię z użyciem intrinsics instrukcje nie zostały włączone w czasie kompilacji (np -march=native
lub -mavx2 -mbmi2 -mpopcnt -mfma -mcx16 -mtune=znver1
lub cokolwiek).
MSVC i ICC pozwolą Ci korzystać z funkcji wewnętrznych bez włączania czegokolwiek w czasie kompilacji, ale nadal powinieneś włączyć AVX przed użyciem funkcji wewnętrznych AVX.
Historycznie (przed immintrin.h
ściągnięciem wszystkiego) trzeba było ręcznie dołączyć nagłówek dla najwyższego poziomu elementów wewnętrznych, jakie chciałeś.
Może to być nadal przydatne w przypadku MSVC i ICC, aby powstrzymać się od używania zestawów instrukcji, których nie chcesz wymagać.
<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
Włączanie jednego z tych ciągów do wszystkich poprzednich (z wyjątkiem SSE4A tylko dla AMD: immintrin.h
nie przyciąga tego)
Niektóre kompilatory mają również <zmmintrin.h>
AVX512.
#include <x86intrin.h>
wciągnąć wszystko, czego potrzebujesz.<zmmintrin.h>
bezpośrednio; gcc nawet tego nie dostarcza. Po prostu użyj<immintrin.h>
lub jeszcze bardziej kompletne<x86intrin.h>
. Ta odpowiedź jest w zasadzie przestarzała, chyba że celowo unikasz włączania elementów wewnętrznych dla nowszych wersji SSE, ponieważ Twój kompilator nie narzeka, gdy używasz instrukcji SSE4.1 podczas kompilacji dla SSE2. (gcc / dzyń nie narzekają, więc należy po prostu użyć immintrin.h dla nich IDK o innych..)W GCC / clang, jeśli używasz tylko
będzie zawierał wszystkie nagłówki SSE / AVX, które są włączone zgodnie z przełącznikami kompilatora, takimi jak
-march=haswell
lub tylko-march=native
. Dodatkowo niektóre instrukcje specyficzne dla x86, takie jakbswap
lubror
stają się dostępne jako wewnętrzne.Odpowiednik MSVC tego nagłówka
<intrin.h>
Jeśli chcesz tylko przenośnej karty SIMD, użyj
#include <immintrin.h>
MSVC, ICC i gcc / clang (i inne kompilatory, jak myślę, Sun, jak sądzę) obsługują ten nagłówek dla funkcji SIMD udokumentowanych przez jedyne wewnętrzne narzędzie do wyszukiwania / wyszukiwania firmy Intel: https://software.intel.com/sites/landingpage/IntrinsicsGuide /
źródło
<x86intrin.h>
, ale<intrin.h>
osiąga podobny efekt. Oczywiście nadal potrzebujesz kompilacji warunkowej. :-(#include <immintrin.h>
. Użyj tego do wewnętrznych elementów SIMD. Potrzebujesz tylko jeszcze większego (i nieco wolniejszego w kompilatorze)x86intrin.h
lubintrin.h
jeśli potrzebujesz takich elementów, jak wewnętrzne funkcje rotacji liczb całkowitych / skanowania bitowego (chociaż Intel dokumentuje niektóre z nich jako dostępneimmintrin.h
w ich przewodniku wewnętrznym ).x86intrin.h
/intrin.h
ale nie wimmintrin.h
.Nazwa nagłówka zależy od kompilatora i architektury docelowej.
intrin.h
x86intrin.h
arm_neon.h
mmintrin.h
altivec.h
spe.h
Możesz obsłużyć wszystkie te przypadki za pomocą dyrektyw warunkowego przetwarzania wstępnego:
źródło
Z tej strony
Więc ogólnie możesz po prostu dołączyć,
immintrin.h
aby uzyskać wszystkie rozszerzenia Intel lubx86intrin.h
jeśli chcesz wszystko, w tym_bit_scan_forward
i_rdtsc
, a także wszystkie wewnętrzne elementy wektorowe obejmują tylko te AMD. Jeśli sprzeciwiasz się dodawaniu więcej, których faktycznie potrzebujesz, możesz wybrać odpowiednie uwzględnienie, patrząc na tabelę.x86intrin.h
to zalecany sposób na zdobycie elementów wewnętrznych dla AMD XOP (tylko Bulldozer, nawet przyszłych procesorów AMD) , zamiast posiadania własnego nagłówka.Niektóre kompilatory nadal będą generować komunikaty o błędach, jeśli użyjesz funkcji wewnętrznych dla zestawów instrukcji, których nie włączyłeś (np.
_mm_fmadd_ps
Bez włączenia fma, nawet jeśli włączyszimmintrin.h
i włączysz AVX2).źródło
smmintrin
(SSE4.1) to Penryn (45 nm Core2), a nie Nehalem („i7”). Czy możemy przestać używać „i7” jako nazwy architektury? Nie ma to znaczenia teraz, gdy Intel nadal używa go w rodzinie SnB .immintrin.h
nie wydaje się zawierać_popcnt32
i_popcnt64
(nie mylić z tymi wpopcntintrin.h
!) funkcji wewnętrznych w GCC 9.1.0. Więc wydaje się, żex86intrin.h
nadal służy celowi.20200914: najnowsze najlepsze praktyki:
<immintrin.h>
(obsługiwane również przez MSVC )Resztę odpowiedzi pozostawię dla celów historycznych; może być przydatny w przypadku starszych kombinacji kompilator / platforma ...
Jak stwierdzono w wielu odpowiedziach i komentarzach,
<x86intrin.h>
znajduje się obszerny nagłówek dotyczący funkcji wewnętrznych x86 [-64] SIMD. Zawiera również wewnętrzne instrukcje wspierające inne rozszerzenia ISA.gcc
,clang
iicc
wszyscy się na tym zdecydowali. Musiałem trochę poszperać w wersjach obsługujących nagłówek i pomyślałem, że warto byłoby wymienić niektóre ustalenia ...gcc : obsługa
x86intrin.h
pierwszego pojawia się wgcc-4.5.0
. Seriagcc-4
wydań nie jest już aktualizowana, podczas gdygcc-6.x
jest to aktualna seria stabilnych wydań.gcc-5
wprowadził również__has_include
rozszerzenie obecne we wszystkichclang-3.x
wersjach.gcc-7
jest w wersji wstępnej (testy regresyjne itp.) i zgodnie z obecnym schematem wersji zostanie wydana jakogcc-7.1.0
.clang :
x86intrin.h
wydaje się być obsługiwany we wszystkichclang-3.x
wersjach. Najnowsza stabilna wersja toclang (LLVM) 3.9.1
. Gałąź rozwoju toclang (LLVM) 5.0.0
. Nie jest jasne, co stało się z4.x
serią.Apple clang : irytujące, wersje Apple nie odpowiadają wersjom
LLVM
projektów. To powiedziawszy, obecne wydanie:clang-800.0.42.1
jest oparte naLLVM 3.9.0
.LLVM 3.0
Wygląda na to, że pierwsza wersja bazowaApple clang 2.1
powróciłaXcode 4.1
.LLVM 3.1
po raz pierwszy pojawia się zApple clang 3.1
(liczbowym zbiegiem okoliczności) wXcode 4.3.3
.Apple definiuje również
__apple_build_version__
np8000042
. Wydaje się, że jest to najbardziej stabilny, ściśle rosnący schemat wersjonowania. Jeśli nie chcesz obsługiwać starszych kompilatorów, ustaw jedną z tych wartości jako minimalne wymaganie.Każda najnowsza wersja
clang
, w tym wersje Apple, nie powinna zatem mieć problemu zx86intrin.h
. Oczywiście wraz zgcc-5
zawsze możesz użyć:Jedną sztuczką, na której nie możesz naprawdę polegać, jest używanie
__GNUC__
wersji wclang
. Wersjonowanie utknęło ze względów historycznych4.2.1
. Wersja poprzedzającax86intrin.h
nagłówek. Czasami jest przydatny, powiedzmy, w przypadku prostych rozszerzeń GNU C, które pozostały wstecznie kompatybilne.icc : o ile wiem,
x86intrin.h
nagłówek jest obsługiwany od co najmniej Intel C ++ 16.0. Test wersji może być wykonywane z:#if (__INTEL_COMPILER >= 1600)
. Ta wersja (i prawdopodobnie wcześniejsze wersje) zapewnia również obsługę__has_include
rozszerzenia.MSVC : Wygląda na
MSVC++ 12.0 (Visual Studio 2013)
to, że jest to pierwsza wersja, która zawieraintrin.h
nagłówek - niex86intrin.h
... to sugeruje:#if (_MSC_VER >= 1800)
jako test wersji. Oczywiście, jeśli próbujesz napisać kod, który jest przenośny we wszystkich tych różnych kompilatorach, nazwa nagłówka na tej platformie będzie najmniejszym z twoich problemów.źródło