さまざまなx86 SIMD命令セット拡張(MMX、SSE、AVXなど)の組み込み関数を提供するヘッダーファイルはどれですか?そのようなリストをオンラインで見つけることは不可能のようです。私が間違っている場合は修正してください。
<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
あなただけを使用する場合
#include <x86intrin.h>
-march=corei7
または単に-march=native
などのコンパイラスイッチに応じて有効にされるすべてのSSE/AVXヘッダーが含まれます。さらに、bswap
やror
などのx86固有の命令が組み込み関数として使用可能になります。
ヘッダー名は、コンパイラとターゲットアーキテクチャによって異なります。
intrin.h
を使用しますx86intrin.h
を使用しますarm_neon.h
を使用しますmmintrin.h
を使用しますaltivec.h
を使用しますspe.h
を使用します条件付き前処理ディレクティブを使用して、これらすべてのケースを処理できます。
#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
これから ページ
+----------------+------------------------------------------------------------------------------------------+
| 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 |
+----------------+------------------------------------------------------------------------------------------+
したがって、一般的には、immintrin.h
を含めてすべてのIntel拡張機能を取得するか、x86intrin.h
および_bit_scan_forward
を含むすべてが必要な場合は_rdtsc
を含めることができます。 -1つだけ。実際に必要なものをさらに含めることに反対する場合は、テーブルを見て正しいインクルードを選択できます。
x86intrin.h
は、独自のヘッダーを持つのではなく、 AMD XOP(ブルドーザーのみ、将来のAMD CPUでさえない) の組み込み関数を取得するための推奨される方法です。
有効になっていない命令セットに組み込み関数を使用すると、一部のコンパイラは引き続きエラーメッセージを生成します(例:_mm_fmadd_ps
を含めてAVX2を有効にしても、fmaを有効にせずにimmintrin.h
)。
回答とコメントの多くが述べているように、<x86intrin.h>
はthe x86 [-64] SIMD組み込み関数の包括的なヘッダーです。また、他のISA拡張機能の命令をサポートする組み込み関数も提供します。 gcc
、clang
、およびicc
はすべてこれで解決しました。私はヘッダーをサポートするバージョンを掘り下げる必要があり、いくつかの調査結果をリストすることが役立つと思いました...
gcc:x86intrin.h
のサポートが最初に表示されるのはgcc-4.5.0
です。 gcc-4
リリースシリーズは現在メンテナンスされていませんが、gcc-6.x
はcurrent安定リリースシリーズです。 gcc-5
は、__has_include
リリースすべてに存在するclang-3.x
拡張も導入しました。 gcc-7
はプレリリース(回帰テストなど)であり、現在のバージョン管理スキームに従って、gcc-7.1.0
としてリリースされます。
clang:x86intrin.h
はすべてのclang-3.x
リリースでサポートされているようです。最新の安定版リリースはclang (LLVM) 3.9.1
です。開発ブランチはclang (LLVM) 5.0.0
です。 4.x
シリーズに何が起こったのかは明確ではありません。
Apple clang:面倒なことに、Appleのバージョン管理はLLVM
プロジェクトのバージョン管理に対応していません。つまり、現在のリリース:clang-800.0.42.1
は、LLVM 3.9.0
に基づいています。最初のLLVM 3.0
ベースのバージョンは、Apple clang 2.1
に戻るXcode 4.1
のようです。 LLVM 3.1
は、Apple clang 3.1
で最初にXcode 4.3.3
(数値の一致)とともに表示されます。
Appleは__Apple_build_version__
も定義します(例:8000042
)。これは、利用可能な最も安定した、厳密に昇順のバージョン管理スキームについてのようです。レガシーコンパイラをサポートしたくない場合は、これらの値のいずれかを最小要件にしてください。
したがって、Appleバージョンを含むclang
の最近のバージョンでは、x86intrin.h
に問題はありません。もちろん、gcc-5
とともに、次のものをいつでも使用できます。
#if defined (__has_include) && (__has_include(<x86intrin.h>))
#include <x86intrin.h>
#else
#error "upgrade your compiler. it's free..."
#endif
本当に頼りにできないトリックの1つは、clang
で__GNUC__
バージョンを使用することです。バージョン管理は、歴史的な理由により、4.2.1
で止まっています。 x86intrin.h
ヘッダーの前にあるバージョン。たとえば、下位互換性を維持している単純なGNU C拡張に対して有用です。
icc:私の知る限り、x86intrin.h
ヘッダーは少なくともIntel C++ 16.0以降でサポートされています。バージョンテストは、#if (__INTEL_COMPILER >= 1600)
で実行できます。このバージョン(および場合によっては以前のバージョン)は、__has_include
拡張機能のサポートも提供します。
MSVC:MSVC++ 12.0 (Visual Studio 2013)
がintrin.h
ヘッダーを提供する最初のバージョンであるようです-notx86intrin.h
...これは、バージョンテストとして#if (_MSC_VER >= 1800)
を示唆しています。もちろん、これらすべての異なるコンパイラー間で移植可能なコードを作成しようとしている場合、このプラットフォームのヘッダー名が問題の最小になります。