x86 SIMD組み込みのヘッダーファイル


131

異なるx86 SIMD命令セット拡張(MMX、SSE、AVXなど)の組み込み機能を提供するヘッダーファイルはどれですか。そのようなリストをオンラインで見つけることは不可能のようです。私が間違っている場合は修正してください。

回答:


174

最近は、通常はだけを含める必要があります<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にも対応しています。


62
または#include <x86intrin.h>、必要なものをすべて取り込むこともできます。
ポールR

2
zmmintrin.hにはAVX-512コンパイラ組み込み関数があります。
オニタケ2014年

3
SSE3 / SSSE3 / SSE4.1および4.2でp、t、s、nが使用されるのはなぜですか?それらのキャラクターは何を表していますか?
phuclv 2015年

5
@LưuVĩnhPhúcSSE3 = Prescottの新しい命令、SSSE3 = Tejasの新しい命令。SSE4.2とAESは、NehalemとWestmereで紹介されたプロセッサフ​​ァミリを指していると思います
Drew McGowen

14
<zmmintrin.h>直接含めないでください。gccはそれを提供していません。または、さらに完全なを使用<immintrin.h>してください<x86intrin.h>。SSE2のコンパイル中にSSE4.1命令を使用してもコンパイラーが文句を言わないため、SSEの新しいバージョンの組み込み関数を意図的に含めない限り、この回答は基本的には時代遅れです。(gcc / clang 文句を言うので、immintrin.hを使用する必要があります。他のユーザーについてはIDKです。)
Peter Cordes

76

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 /


新しいバージョンの可能性があるかどうかはわかりませんでした...とにかく、gcc、icc、clangにそれがある限り、使用しても問題ないと思います:-)
Gunther Piez

5
MSVCにははありませんが<x86intrin.h><intrin.h>同様の効果があります。もちろん、まだ条件付きコンパイルが必要です。:-(
コーディグレイ

すべての主要なx86コンパイラにはがあり#include <immintrin.h>ます。SIMD組み込み関数に使用します。必要なのは、さらに大きい(コンパイラーの方が少し遅い)x86intrin.hintrin.h、整数回転/ビットスキャン組み込み関数などが必要な場合のみです(ただし、Intel immintrin.h は、組み込み関数ガイドで利用できるものとしてそれらの一部を文書化しています)。
Peter Cordes

IIRC、いくつかの非SIMD組み込み関数たインテルの文書がimmintrin.hであるとありますが、これはgcc、打ち鳴らす、および/またはMSVCのみを持っているx86intrin.h/ intrin.hしかしありませんimmintrin.h
Peter Cordes

56

ヘッダー名は、コンパイラとターゲットアーキテクチャによって異なります。

  • Microsoft C ++(ターゲットx86、x86-64またはARM)およびWindows用Intel C / C ++コンパイラの場合 intrin.h
  • x86 / x86-64をターゲットとするgcc / clang / iccの場合 x86intrin.h
  • NEONを使用するARMをターゲットとするgcc / clang / armccの場合 arm_neon.h
  • WMMXを使用してARMをターゲットとするgcc / clang / armccの場合 mmintrin.h
  • VMX(別名Altivec)またはVSXでPowerPCをターゲットとするgcc / clang / xlccの場合 altivec.h
  • SPEを使用するPowerPCをターゲットとするgcc / clangの場合 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

リストに追加するいくつかの項目を次に示します。gccを使用するUltraSPARC + VISでは、visintrin.hを使用します。SunのVSDKを使用している場合、vis.hは異なる組込み関数を提供します。ドキュメントはここにあります:GCC VIS builtinsSun VIS user's guide
オニタケ2014年

44

このページから

+----------------+------------------------------------------------------------------------------------------+
|     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を有効にしない)に組み込み関数を使用すると、エラーメッセージを生成します。


1
smmintrin(SSE4.1)は、Nehalem( "i7")ではなくPenryn(45nm Core2)です。アーキテクチャ名として「i7」の使用をやめることはできますか? IntelがこれをSnBファミリで使用し続けているのは今では意味がありません
Peter Cordes 2016年

immintrin.h含まれるように表示されていない_popcnt32_popcnt64(のものと混同しないようにpopcntintrin.hGCC 9.1.0の組み込み関数を!)。したがって、それはx86intrin.hまだ目的を果たしているように見えます。
Thom Wiggers

12

回答やコメントの多くが述べたように、<x86intrin.h>あるx86のための包括的なヘッダ[-64] SIMD組み込み関数は。また、他のISA拡張の命令をサポートする組み込み関数も提供します。、、そしてこのすべてに落ち着いてきました。ヘッダーをサポートするバージョンを掘り下げる必要があり、いくつかの調査結果をリストすることは役立つと思いました...gccclangicc

  • gccx86intrin.h最初のサポートはに現れますgcc-4.5.0gcc-4リリースシリーズは、もはや維持されて、しばらくはgcc-6.xありません、現在の安定リリースシリーズ。すべてのリリースに存在gcc-5する__has_include拡張機能も導入されましたclang-3.xgcc-7はプレリリース(リグレッションテストなど)であり、現在のバージョン管理スキームに従って、としてリリースされgcc-7.1.0ます。

  • clangx86intrin.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)バージョンのテストとして。もちろん、これらすべての異なるコンパイラー間で移植可能なコードを記述しようとしている場合、このプラットフォームのヘッダー名が問題の最小になります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.