ループのベクトル化を実行します。
#pragma simd [clause[ [,] clause]...] |
clause |
次のいずれかです。
|
より多くのループのベクトル化を行うようにコンパイラーに指示するには、simd プラグマを使用します。simd プラグマを使用したベクトル化は、完全に自動化されたアプローチを補完します (ただし、置き換えることはできません)。
明示的に vectorlength() 節または vectorlengthfor() 節が指定されていない場合、コンパイラーは独自のコストモデルを使用して vectorlength を選択します。private、 firstprivate、 lastprivate、 linear、および reduction で正しくない変数が指定されたり、あるいは適切な変数が指定されていない場合、ランタイムエラーや正しくない結果など、意図しない問題が発生する可能性があります。
特定の変数は、private、 linear、または reduction 節の 1 つのインスタンスでのみ指定することができます。
コンパイラーがループをベクトル化できない場合は、警告が出力されます (assert 節を使用して警告をエラーとすることができます)。
なんらかの理由でベクトル化機能がループのベクトル化を停止する必要がある場合は、SIMD ループに fast 浮動小数点モデルが使用されます。
ループを simd プラグマでベクトル化すると、-fp-model オプション (Linux*) および /fp オプション (Windows*) で指定された設定は無効になります。
-fp-model は C++ でのみ利用できます。DPC++ では利用できません。
simd プラグマは、すべての自動ベクトル化が可能なループに影響するわけではありません。いくつかのループでは SIMD ベクトル・セマンティクスを表現できません。
simd プラグマには、次の制限が適用されます
simd プラグマの可算ループは、OpenMP* のワークシェア・ループ構造の for ループ形式に準拠していなければなりません。また、ループ制御変数は符号付き整数型でなければなりません。
ベクトル値は、8、16、32、または 64 ビットの符号付き整数、単精度または倍精度の浮動小数点数、あるいは単精度または倍精度の複素数でなければなりません。
SIMD ループには別のループ (for、 while、 do-while) が入れ子される場合があります。入れ子構造のループの内側から外側へのジャンプはサポートされていません。ブレークと継続はサポートされています。
SIMD ループは無条件にメモリー参照を実行します。そのため、すべてのアドレス計算結果は、ループがシーケンシャルに実行されたときにはアクセスされなくても、有効なメモリーアドレスでなければなりません。
ユーザー指示によるベクトル化 (SIMD ベクトル化とも呼ぶ) では、#pragma simd アノテーション付きのループのベクトル化に失敗した場合、エラーを報告するかどうか指定できます。デフォルトでは、simd プラグマは noassert に設定されていて、ループのベクトル化に失敗すると、コンパイラーは警告を発行します。#pragma simd アノテーション付きのループのベクトル化に失敗した場合、コンパイラーにエラーを報告するように指示するには、simd プラグマに assert 節を追加します。simd アノテーション付きのループがコンパイラーによりベクトル化されなかった場合、そのループはシリアル・セマンティクスを保持します。
simd プラグマの使用例 |
---|
|
上の例では、関数 add_floats() で不明なポインターを多く使用しているため、コンパイラーの自動ランタイム独立性チェックによる最適化が行われます。simd プラグマを使用してこのループのベクトル化を行うことで、ランタイムチェックにかかるオーバーヘッドを回避することができます。