異なるx86 SIMD命令セット拡張(MMX、SSE、AVXなど)の組み込み機能を提供するヘッダーファイルはどれですか。そのようなリストをオンラインで見つけることは不可能のようです。私が間違っている場合は修正してください。
異なるx86 SIMD命令セット拡張(MMX、SSE、AVXなど)の組み込み機能を提供するヘッダーファイルはどれですか。そのようなリストをオンラインで見つけることは不可能のようです。私が間違っている場合は修正してください。
回答:
最近は、通常はだけを含める必要があります<immintrin.h>
。すべてが含まれています。
GCCとclangを使用すると、コンパイル時に有効にしていない命令に組み込み関数を使用できなくなります(例:-march=native
または、または-mavx2 -mbmi2 -mpopcnt -mfma -mcx16 -mtune=znver1
その他)。
MSVCとICCを使用すると、コンパイル時に何も有効にせずに組み込み関数を使用できますが、AVX組み込み関数を使用する前にAVX を有効にする必要があります。
歴史的に(immintrin.h
すべてを取り込む前に)必要な組み込みの最高レベルのヘッダーを手動で含める必要がありました。
これは、MSVCおよびICCで、不要な命令セットを使用しないようにする場合にも役立ちます。
<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
以前のすべてにこれらのプルの1つを含める(AMDのみのSSE4Aを除く:immintrin.h
プルしない)
一部のコンパイラ<zmmintrin.h>
はAVX512にも対応しています。
<zmmintrin.h>
直接含めないでください。gccはそれを提供していません。または、さらに完全なを使用<immintrin.h>
してください<x86intrin.h>
。SSE2のコンパイル中にSSE4.1命令を使用してもコンパイラーが文句を言わないため、SSEの新しいバージョンの組み込み関数を意図的に含めない限り、この回答は基本的には時代遅れです。(gcc / clang は文句を言うので、immintrin.hを使用する必要があります。他のユーザーについてはIDKです。)
GCC / clangでは、
#include <x86intrin.h>
-march=haswell
またはのようなコンパイラスイッチに従って有効にされるすべてのSSE / AVXヘッダーが含まれます-march=native
。さらに、一部のx86固有の命令は、組み込みのように、bswap
またはror
組み込みとして利用可能になります。
このヘッダーに相当するMSVC <intrin.h>
ポータブルSIMDだけが必要な場合は、 #include <immintrin.h>
MSVC、ICC、およびgcc / clang(そして私が考えるSunのような他のコンパイラー)はすべて、インテルの唯一の組み込み関数ファインダー/検索ツールによって文書化されたSIMD組み込み関数のこのヘッダーをサポートします:https : //software.intel.com/sites/landingpage/IntrinsicsGuide /
<x86intrin.h>
、<intrin.h>
同様の効果があります。もちろん、まだ条件付きコンパイルが必要です。:-(
#include <immintrin.h>
ます。SIMD組み込み関数に使用します。必要なのは、さらに大きい(コンパイラーの方が少し遅い)x86intrin.h
かintrin.h
、整数回転/ビットスキャン組み込み関数などが必要な場合のみです(ただし、Intel immintrin.h
は、組み込み関数ガイドで利用できるものとしてそれらの一部を文書化しています)。
x86intrin.h
/ intrin.h
しかしありませんでimmintrin.h
。
ヘッダー名は、コンパイラとターゲットアーキテクチャによって異なります。
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
、すべてのベクトル組み込みにAMD専用の組み込みを含めることができます。実際に必要なものを含めることに反対の場合は、表を見て適切なインクルードを選択できます。
x86intrin.h
独自のヘッダーを持つのではなく、AMD XOP(ブルドーザーのみ、将来のAMD CPUでさえない)の組み込みを取得するための推奨される方法です。
一部のコンパイラーは、有効にしていない命令セット(たとえば、AVX2 _mm_fmadd_ps
を含めimmintrin.h
て有効にした場合でも、fmaを有効にしない)に組み込み関数を使用すると、エラーメッセージを生成します。
smmintrin
(SSE4.1)は、Nehalem( "i7")ではなくPenryn(45nm Core2)です。アーキテクチャ名として「i7」の使用をやめることはできますか? IntelがこれをSnBファミリで使用し続けているのは今では意味がありません。
immintrin.h
含まれるように表示されていない_popcnt32
と_popcnt64
(のものと混同しないようにpopcntintrin.h
GCC 9.1.0の組み込み関数を!)。したがって、それはx86intrin.h
まだ目的を果たしているように見えます。
回答やコメントの多くが述べたように、<x86intrin.h>
あるx86のための包括的なヘッダ[-64] SIMD組み込み関数は。また、他のISA拡張の命令をサポートする組み込み関数も提供します。、、そしてこのすべてに落ち着いてきました。ヘッダーをサポートするバージョンを掘り下げる必要があり、いくつかの調査結果をリストすることは役立つと思いました...gcc
clang
icc
gcc:x86intrin.h
最初のサポートはに現れますgcc-4.5.0
。gcc-4
リリースシリーズは、もはや維持されて、しばらくはgcc-6.x
ありません、現在の安定リリースシリーズ。すべてのリリースに存在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
。これは、利用可能な最も安定した、厳密に昇順のバージョン管理スキームについてのようです。レガシーコンパイラをサポートしたくない場合は、これらの値の1つを最小要件にします。
clang
したがって、Appleのバージョンを含むの最近のバージョンでは、に問題はありません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つは、の__GNUC__
バージョンを使用することですclang
。バージョン管理は、歴史的な理由により、で止まってい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
-ヘッダません x86intrin.h
:...これは示唆している#if (_MSC_VER >= 1800)
バージョンのテストとして。もちろん、これらすべての異なるコンパイラー間で移植可能なコードを記述しようとしている場合、このプラットフォームのヘッダー名が問題の最小になります。
#include <x86intrin.h>
、必要なものをすべて取り込むこともできます。