ベクトル化とループ

ここでは、自動ベクトル化とループの相互作用について詳しく説明します。

「ベクトル化のプログラミングにおけるガイドライン」を参照してください。

まれに、(自動または OpenMP* ディレクティブのいずれかによって) ループ並列化が成功すると、コンパイラーにレポートされるベクトル化されなかったループのメッセージに影響することがあります。

ベクトル化されるループの種類

整数ループの場合、128 ビットのインテル® ストリーミング SIMD 拡張命令 (インテル® SSE) とインテル® アドバンスト・ベクトル・エクステンション (インテル® AVX) は 32 ビット、16 ビット、8 ビット、および限定対応の 64 ビットの整数データ型を使用するほとんどの算術演算子と論理演算子に対して SIMD 命令を提供します。

整数丸め演算の最終的な精度が保持される場合は、ベクトル化が可能です。例えば、最後に格納された値が 16 ビット整数である場合には、32 ビットの右シフト演算子は 16 ビット・モードではベクトル化されません。また、インテル® SSE およびインテル® AVX 命令セットは完全に直交型ではない (例えば、バイト・オペランドのシフトはサポートされていない) ため、実際にはすべての整数演算をベクトル化ができないので注意してください。

32 ビット単精度および 64 ビット倍精度の浮動小数点数を操作するループの場合、インテル® SSE は次の算術演算子に対して SIMD 命令を提供します。

また、インテル® SSE は、MINMAX という二項演算子、および SQRT という単項演算子に SIMD 命令を提供しています。これ以外の複数の算術演算子の SIMD バージョン (三角関数 SINCOSTAN など) は、インテル® oneAPI DPC++/C++ コンパイラーで提供されるベクトル数値ランタイム・ライブラリー内のソフトウェアでサポートしています。

ベクトル化が可能であるためには、ループは次の条件を満たしていなければなりません。

算術組込み関数は、コンパイラーのランタイム・ライブラリーにベクトル化されたバージョンが含まれているため、利用できます。このような関数を次にリストします。多くは float と double の両方があります。

acos ceil fabs round
acosh cos floor sin
asin cosh fmax sinh
asinh erf fmin sqrt
atan erfc log tan
atan2 erfinv log10 tanh
atanh exp log2 trunc
cbrt exp2 pow  

ループ本体内の文

ベクトル化可能な演算は、浮動小数点データと整数データとで異なります。

整数配列の演算

ループ本体内の文では、charunsigned charshortunsigned shortintunsigned int 型を使用できます。sqrtfabs といった関数を呼び出すこともできます。使用可能な算術演算は、加算、減算、ビット単位 AND、ビット単位 OR、ビット単位 XOR、除算 (ランタイム・ライブラリー・コール経由)、乗算、min、および max だけです。データ型は混在させられますが、効率性の低下につながる恐れがあります。例えば、乗算演算子、シフト演算子、単項演算子は混在させられます。

その他の演算

上記の浮動小数点演算と整数演算以外の文は使用できません。特に、特殊なデータ型である __m64__m128__m256 はベクトル化できないので注意してください。ループ本体に関数呼び出しを含めることはできません。インテル® SSE の組込み関数 (例: _mm_add_ps) またはインテル® AVX 組込み関数 (例: _mm256_add_ps) は使用できません。

性能は、使用法、構成、およびその他の要因によって異なります。詳細については、www.Intel.com/PerformanceIndex (英語) を参照してください。

注意事項の改訂 #20201201

関連情報