インテル® Advanced Vector Extensions (インテル® AVX) の詳細

インテル® Advanced Vector Extensions (インテル® AVX) 組み込み関数は、インテル® AVX 命令およびその他の 128 ビットの SIMD (Single Instruction, Multiple Data) 拡張命令に直接対応付けられます。インテル® AVX 命令は、既存のインテル® ストリーミング SIMD 拡張命令 (インテル® SSE) のインテル® 64 アーキテクチャー用ベクトル命令とインテル® ストリーミング SIMD 拡張命令 2 (インテル® SSE2) の倍精度浮動小数点組み込み関数に似ています。ただし、インテル® AVX には、次の点が追加されています。

インテル® AVX レジスター

インテル® AVX では、16 個のレジスター (YMM0-YMM15) が追加されています。各レジスターは 256 ビットで、16 個の SIMD (XMM0-XMM15) レジスターにエイリアスされています。インテル® AVX の新しい命令は、YMM レジスターのデータを操作します。インテル® AVX は、1 つの命令で最大 3 つのソースと 1 つのデスティネーションをエンコードする新しい方法を定義して、YMM レジスターのデータを操作するために一部の既存の命令を拡張しています。

各レジスターは複数のデータ要素を保持できるため、プロセッサーは複数のデータ要素を同時に処理できます。このような処理方法は、SIMD (Single Instruction, Multiple Data) 処理と呼ばれます。

新しい拡張命令セットのそれぞれの計算命令とデータ操作命令について、その命令を直接実行する C 組み込み関数が用意されています。これにより、プログラマーは、レジスターの管理とアセンブリー言語のプログラミングを行う必要がなくなります。また、コンパイラーは、命令のスケジューリングを最適化して、実行ファイルの処理速度を上げることができます。

インテル® AVX のデータ型

インテル® 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) であることを示します。その他の文字は、次のデータ型を示します。
  • s 単精度浮動小数点値
  • d 倍精度浮動小数点値
  • i128 符号付き 128 ビット整数
  • i64 符号付き 64 ビット整数
  • u64 符号なし 64 ビット整数
  • i32 符号付き 32 ビット整数
  • u32 符号なし 32 ビット整数
  • i16 符号付き 16 ビット整数
  • u16 符号なし 16 ビット整数
  • i8 符号付き 8 ビット整数
  • u8 符号なし 8 ビット整数
  • ps パックド単精度浮動小数点値
  • pd パックド倍精度浮動小数点値
  • sd スカラー倍精度浮動小数点値
  • epi32 拡張パックド 32 ビット整数
  • si256 スカラー 256 ビット整数
<data type> パラメーターのデータ型: __m256__m256d__m256i__m128__m128d__m128iconst 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);

説明:

add
加算が実行されることを示します。
pd
パックド倍精度浮動小数点値を示します。

パックされた値は、右から左の順序で表し、最下位の値がスカラー操作に使用されます。 次の例について考えてみます。

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 です。一部の組み込み関数では、命令の性質上、引数として即値 (定数整数) を指定しなければなりません。