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