ベクトル化コンパイラーの目的は、自動的に SIMD (single-instruction multiple data) 処理を活用することです。コンパイラーに (宣言子などを使用して) 追加情報を提供することで、コンパイラーのベクトル化を助けます。
ループに変更が必要な場合がよくあります。ループ本体のガイドラインに従ってください。
好ましいもの
わかりやすいコード (単一の基本ブロック)
ベクトルデータのみ。すなわち、代入文の右辺には、配列と不変式を使用します。代入式の左辺には配列参照を使用してもかまいません。
代入文のみ
避けるべきもの
関数呼び出し
ベクトル化できない演算 (算術以外)
ベクトル化できる複数の型を同じループの中に混在させること
データ依存性を持つループ出口条件
ベクトル化可能なコードに変えるには、ループを変更しなければならない場合がよくあります。ただし、変更する部分は、ベクトル化に最低必要なところだけとし、他の部分まで変更しないようにしてください。特に、次の項目に注意してください。
ループのアンロールはしないこと。これはコンパイラーが自動的に行います。
本体の中で複数の文で構成している 1 つのループを複数の単文ループに解体すること。
注意が必要な制約条件があります。ベクトル化は、ハードウェアとソースコードのスタイルの 2 つの主要な要因により制約されます。
要因 |
説明 |
---|---|
ハードウェア |
コンパイラーは、それを動かすハードウェアからいくつか制約を受けます。ストリーミング SIMD 拡張命令を実行する場合、ベクトルメモリー演算は、16 バイトでアライメントしたメモリー参照が優先するため、アクセスストライドが 1 に制限されます。つまり、コンパイラーは、たとえループをベクトル化可能と抽象的に認めたとしても、別のターゲット・アーキテクチャーに対してはベクトル化をしないかもしれません。 |
ソースコード |
ソースコードの書き方によっては最適化の妨げになるときもあります。例えば、グローバルポインターを使用する場合に、2 つのメモリー参照が別々の場所で行われるかどうかをコンパイラーが判定できないという問題がよく起こります。そうなると、一部の変換処理は順序の並べ替えができなくなります。 |
コンパイラーによる自動ベクトル化を阻害する多くの要因はループ構造の書きかたにあります。ループ本体にはキーワード、演算子、データ参照、およびメモリー演算が含まれており、それらが互いに作用し合うためループの動作がよく見えなくなるのです。
しかし、これらの制約を理解し、診断メッセージの読みかたを知れば、そうした既知の制約条件を克服して効率よくベクトル化できるようプログラムを修正できます。以降の各セクションでは、ループ構造についてベクトライザーの機能と制約条件を簡単に述べます。