インテル® Advanced Vector Extensions (インテル® AVX) 組み込み関数は、インテル® AVX 命令およびその他の 128 ビットの SIMD (Single Instruction, Multiple Data) 拡張命令に直接対応付けられます。インテル® AVX 命令は、既存のインテル® ストリーミング SIMD 拡張命令 (インテル® SSE) のインテル® 64 アーキテクチャー用ベクトル命令とインテル® ストリーミング SIMD 拡張命令 2 (インテル® SSE2) の倍精度浮動小数点組み込み関数に似ています。ただし、インテル® AVX には、次の点が追加されています。
インテル® AVX では、16 個のレジスター (YMM0-YMM15) が追加されています。各レジスターは 256 ビットで、16 個の SIMD (XMM0-XMM15) レジスターにエイリアスされています。インテル® AVX の新しい命令は、YMM レジスターのデータを操作します。インテル® AVX は、1 つの命令で最大 3 つのソースと 1 つのデスティネーションをエンコードする新しい方法を定義して、YMM レジスターのデータを操作するために一部の既存の命令を拡張しています。
各レジスターは複数のデータ要素を保持できるため、プロセッサーは複数のデータ要素を同時に処理できます。このような処理方法は、SIMD (Single Instruction, Multiple Data) 処理と呼ばれます。
新しい拡張命令セットのそれぞれの計算命令とデータ操作命令について、その命令を直接実行する C 組み込み関数が用意されています。これにより、プログラマーは、レジスターの管理とアセンブリー言語のプログラミングを行う必要がなくなります。また、コンパイラーは、命令のスケジューリングを最適化して、実行ファイルの処理速度を上げることができます。
インテル® AVX の組み込み関数は、3 つの新しい C データ型 (__m256 、__m256d、および __m256i) をオペランドとして使用します。3 つのデータ型は、組み込み関数のオペランドとして使用される新しいレジスターを表しています。
__m256 データ型は、拡張 SSE レジスター (インテル® AVX 組み込み関数で使用される YMM レジスター) の内容を表します。__m256 データ型は、8 つの 32 ビット倍精度浮動小数点値を保持できます。
__m256d データ型は、4 つの 64 ビット倍精度浮動小数点値を保持できます。
__m256i データ型は、32 個の 8 ビット整数値、16 個の 16 ビット整数値、8 個の 32 ビット整数値、または 4 個の 64 ビット整数値を保持できます。
コンパイラーは、__m256、__m256d、および __m256i 型のローカルデータとグローバルデータのアライメントを、スタック上の 32 バイト境界に合わせます。integer 型、float 型、または double 型の配列のアライメントを合わせるには、次のように declspec 文を使用します。
typedef struct __declspec(align(32)) { float f[8]; } __m256;
typedef struct __declspec(align(32)) { double d[4]; } __m256d;
typedef struct __declspec(align(32)) { int i[8]; } __m256i;
インテル® AVX 組み込み関数は、一部の操作で SSE2 の __m128、__m128d、および __m128i に似たデータ型も使用します。
__m128 データ型は、ストリーミング SIMD 拡張命令の組み込み関数に使用するストリーミング SIMD 拡張命令レジスター (XMM) の内容を表します。__m128 データ型は、4 つの 32 ビット浮動小数点値を保持できます。
__m128d データ型は、2 つの 64 ビット浮動小数点値を保持できます。
__m128i データ型は、16 個の 8 ビット整数値、8 個の 16 ビット整数値、4 個の 32 ビット整数値、または 2 個の 64 ビット整数値を保持できます。
ほとんどのインテル® AVX 組み込み関数名は、次の表記規則に従っています。
_mm256_<intrin_op>_<suffix>(<data type> <parameter1>, <data type> <parameter2>, <data type> <parameter3>)
次の表は、構文の各項目について説明したものです。
_mm256 | インテル® AVX の 256 ビットのベクトルレジスターを表すプリフィックス |
<intrin_op> | 組み込み関数の基本操作を示します。例えば、加算の場合は add、減算の場合は sub になります。 |
<suffix> | 命令の操作対象となるデータの型を示します。各サフィックスの最初の 1 文字または 2 文字は、データがパックドデータ (p)、拡張パックドデータ (ep)、またはスカラーデータ (s) であることを示します。その他の文字は、次のデータ型を示します。
|
<data type> | パラメーターのデータ型: __m256、__m256d、__m256i、__m128、__m128d、__m128i、const int、など。 |
<parameter1> | 1 つめのソース・ベクトル・レジスター: m1/s1/a |
<parameter2> | 2 つめのソース・ベクトル・レジスター: m2/s2/b |
<parameter3> |
整数値: mask/select/offset 3 つめのパラメーターのビットは、組み込み関数が操作を実行する条件を示します。 |
extern __m256d _mm256_add_pd(__m256d m1, __m256d m2);
説明:
パックされた値は、右から左の順序で表し、最下位の値がスカラー操作に使用されます。 次の例について考えてみます。
double a[4] = {1.0, 2.0, 3.0, 4.0};
__m256d t = _mm256_load_pd(a);
次の結果が得られます。
__m256d t = _mm256_set_pd(4.0, 3.0, 2.0, 1.0);
つまり、値 t を保持する YMM レジスターは、次のようになります。
"スカラー" 要素は 1.0 です。一部の組み込み関数では、命令の性質上、引数として即値 (定数整数) を指定しなければなりません。