ここでは、simd プラグマの代わりに使用できる _Simd キーワードについて説明します。simd プラグマと同様に、_Simd キーワードはシリアル for ループをベクトル化します。構文は、次のとおりです。
_Simd [_Safelen(constant-expression)][_Reduction (reduction-identifier : list)]
_Simd キーワードと節は、次の例に示すように、for キーワードの後に指定します。
for _Simd (int i=0; i<10; i++){
// ループ本体
}
simd プラグマと _Simd キーワードの相違点は次のとおりです。
- C / C++ の変数のスコープ規則では、ループの反復の範囲内でプライベート変数を宣言できるため、_Simd キーワードには simd プラグマ構文の private 節と lastprivate 節がありません。
- _Simd キーワードは複数の変数をインクリメントできるため、linear 節は不要です。そのため、_Simd キーワードには linear 節がありません。次の例を参照してください。
float add_floats(float *a, float *b, int n){
int i=0;
int j=0;
float sum=0;
for _Simd _Reduction(+:sum) (i=0; i<n; i++, j+=2){
a[i] = a[i] + b[j];
sum += a[i];
}
return sum;
}
ループが確実にベクトル化されるように、次の点を考慮してください。
- _Simd キーワードを指定する加算ループは、incr-expr で複数の変数をインクリメントできることを除き、OpenMP* の標準的な for ループ形式でなければなりません (www.openmp.org (英語) の OpenMP* 仕様を参照)。
- ループ制御変数は符号付き整数型でなければなりません。
- ベクトル値は、8、16、32、または 64 ビットの符号付き整数、単精度または倍精度の浮動小数点数、あるいは単精度または倍精度の複素数でなければなりません。
- SIMD ループへのジャンプ、または SIMD ループからのジャンプを行う制御文 (break、return、goto、throw を含む) を使用してはなりません。
- SIMD ループに別のループ (for、while、do-while) を含められますが、入れ子されたループからの goto 文によるジャンプはサポートされていません。break および continue 文は、入れ子されたループで使用することができます。
- SIMD ループは無条件にメモリー参照を実行します。そのため、すべてのアドレス計算結果は、ループがシーケンシャルに実行されたときにはアクセスされなくても、有効なメモリーアドレスでなければなりません。