インテル® C++ コンパイラー 18.0 デベロッパー・ガイドおよびリファレンス

vector

ループを引数キーワードに従ってベクトル化するようにコンパイラーに指示します。

構文

#pragma vector {always[assert]|aligned|unaligned|temporal|nontemporal|[no]vecremainder|[no]mask_readwrite}

#pragma vector nontemporal[(var1[, var2,...])]

引数

always

ベクトル化するかどうかを決定する際、効率ヒューリスティックを無効にするようにコンパイラーに指示します。非ユニットストライドまたはほとんどアライメントの合っていないメモリーアクセスをベクトル化して、プログラムで後に続くループのベクトル化を制御します。オプションで assert キーワードを指定できます。

aligned

ベクトル化の際にすべての配列参照に対して aligned データ移動命令を使用するようにコンパイラーに指示します。

unaligned

ベクトル化の際にすべての配列参照に対して unaligned データ移動命令を使用するようにコンパイラーに指示します。

nontemporal

特に明記されていない限り、サポートされているすべてのアーキテクチャー・ベースのシステムで、一時的ではない (ストリーミング) ストアを使用するようにコンパイラーに指示します。オプションでカンマ区切りの変数リストも指定できます。

このプラグマを指定する場合、単一または複数のスレッド内で正しいメモリーの順序設定が徹底されるように、必要なフェンスを挿入する必要があります。この 1 つの典型的な方法として、コンパイラーがストリーミング・ストア命令を挿入する可能性がある、ループ (例えば、初期化ループ) の直後に _mm_sfence 組込み関数呼び出しを挿入します。

インテル® メニー・インテグレーテッド・コア (インテル® MIC) アーキテクチャー・ベースのシステムでは、一時的ではないプラグマによるストア後に、そのストアアドレスがアライメントされていることが分かっている場合は、clevict (キャッシュラインの削除) 命令を生成するようにコンパイラーに指示します。オプションでカンマ区切りの変数リストも指定できます。

temporal

特に明記されていない限り、サポートされているすべてのアーキテクチャー・ベースのシステムで、一時的な (非ストリーミング) ストアを使用するようにコンパイラーに指示します。

vecremainder

オリジナルのループがベクトル化された場合に残りのループをベクトル化するようにコンパイラーに指示します。

novecremainder

オリジナルのループがベクトル化された場合に残りのループをベクトル化しないようにコンパイラーに指示します。

mask_readwrite

メモリーのスペキュレーションを有効にし、条件内でマスクなしロード/ストア操作を生成します。

nomask_readwrite

メモリーのスペキュレーションを無効にし、条件内でマスク付きロード/ストア操作を生成します。

説明

vector プラグマは、ループのベクトル化が可能である限り、ベクトル化によるメリットの有無に関する通常のヒューリスティックな判断を無視してベクトル化を行うように指示します。vector プラグマは、引数キーワードを使用して必要なループのベクトル化の種類を指定します。キーワードは、alignedunalignedalwaystemporal、および nontemporal です。コンパイラーは入れ子構造のループに vector プラグマを適用しないため、入れ子にされたそれぞれのループの前に、プラグマ文が必要です。loop 制御文の前にプラグマを配置してください。

aligned/unaligned キーワードの使用

このプラグマで aligned/unaligned 引数キーワードが使用された場合、すべての配列参照に対して aligned/unaligned データ移動命令を使用してループをベクトル化することを示します。引数キーワードとして aligned または unaligned のいずれかを指定します。

注意

引数として aligned を指定する場合、ループはこのプラグマを使用してベクトル化可能であることが確実でなければなりません。それ以外の場合、コンパイラーは誤ったコードを生成します。

always キーワードの使用

always 引数キーワードが使用されると、プラグマは後に続くループのベクトル化を制御します。assert を指定すると、コンパイラーはエラーレベルのアサーション・テストを生成し、コンパイラーの効率ヒューリスティックによってループのベクトル化が不可能であることが示す旨のメッセージを表示します。

nontemporal/temporal キーワードの使用

nontemporaltemporal 引数キーワードは、IA-32 およびインテル® 64 アーキテクチャー・ベースのシステムで、レジスター内容のストア方法 (ストリーミングか非ストリーミング) を制御します。

インテル® メニー・インテグレーテッド・コア (インテル® MIC) アーキテクチャー・ベースのシステムでは、#pragma vector nontemporal は、一時的ではないプラグマによるストア後に、そのストアアドレスがアライメントされていることが分かっている場合は、clevict (キャッシュラインの削除) 命令を生成するようにコンパイラーに指示します。オプションでカンマ区切りの変数リストも指定できます。

デフォルトでは、コンパイラーはそれぞれの変数にストリーミング・ストアを使用するかどうかを自動で決定します。

ストリーミング・ストアは、特定のプロセッサーにおいて非ストリーミング・ストアよりも、大幅なパフォーマンスの向上をもたらす可能性があります。ただし、ストリーミング・ストアの使用を誤ると、パフォーマンスが大幅に低下します。

[no]vecremainder キーワードの使用

vector always プラグマとキーワードを同時に指定すると、次の動作になります。

[no]mask_readwrite キーワードの使用

vector プラグマと mask_readwrite または nomask_readwrite キーワードを同時に指定すると、次の動作になります。

vector{always|aligned|unaligned} プラグマは注意して使用してください。

コンパイラーの効率性ヒューリスティックの変更は、ベクトル化によりパフォーマンスが向上することが確実である場合にのみ行います。また、アライメントの合ったデータ移動命令ですべての配列参照をコンパイラーに実装すると、アライメントの合っていないアクセスパターンがある場合にランタイム例外が発生します。

次の例は、aligned 引数キーワードを使用して、aligned 命令でループがベクトル化されるように指示します。

配列は、コンパイラーが通常安全であると証明できないような方法で宣言されています。

vector aligned プラグマの使用例

void vec_aligned(float *a, int m, int c) {
  int i;
  // ベクトル依存性が存在していると推定されてもそれを無視するようにコンパイラーに指示します。
  #pragma vector aligned
  for (i = 0; i < m; i++)
    a[i] = a[i] * c;
  // 不明なアライメントですが、コンパイラーはアライメントすることができます。
  for (i = 0; i < 100; i++)
    a[i] = a[i] + 1.0f; 
}

vector always プラグマの使用例

void vec_always(int *a, int *b, int m) {
  #pragma vector always
  for(int i = 0; i <= m; i++)
    a[32*i] = b[99*i]; 
}

vector nontemporal プラグマの使用例

float a[1000]; 
void foo(int N){
  int i;
  #pragma vector nontemporal
  for (i = 0; i < N; i++) {
    a[i] = 1;
  } 
}

生成されたアセンブリーとのループ (float 型) の例は、次のとおりです。N が大きくなると、インテル® Pentium® 4 プロセッサー・システムで非ストリーミング組込み関数のパフォーマンスが大幅に向上します。

ループ本体の ASM コードの使用例

  .B1.2: 
movntps XMMWORD PTR _a[eax], xmm0 
movntps XMMWORD PTR _a[eax+16], xmm0 
add eax, 32 
cmp eax, 4096 
jl .B1.2

vector nontemporal プラグマと変数を使用するストリーミング・ストアの実装例

double A[1000]; 
double B[1000]; 
void foo(int n){
  int i; 
#pragma vector nontemporal (A, B)
  for (i=0; i<n; i++){
    A[i] = 0;
    B[i] = i;
  } 
}

関連情報