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