ベクトル化のサポート (IA-32)

vector ディレクティブは、プログラム中の後に続くループのベクトル化を制御しますが、コンパイラはネストされたループには適用しません。ネストされたそれぞれのループは、その前に、固有のディレクティブが必要です。vector ディレクティブは、loop 文の前に配置してください。

vector always ディレクティブ

vector always ディレクティブは、ベクトル化するかどうかを決定する際、効率ヒューリスティックを無効にするようコンパイラに命令します。そして 1 以外のストライドまたはほとんどアライメントの合っていないメモリアクセスをベクトル化します。

vector always ディレクティブの例

#pragma vector always

 

for(i=0; i<=N; i++)

{

   a[32*i]=b[99*i];

}

ivdep ディレクティブ

ivdep ディレクティブは、ベクトル依存性が存在していると推定されてもそれを無視するようコンパイラに命令します。正しいコードにするため、コンパイラは、想定される依存性を証明された依存性として扱います。これは、ベクトル化を行わないようにします。このディレクティブは、その決定を無視します。推定されたループの依存性が安全で、無視できる場合にのみ ivdep を使用してください。下記の例のループは、k の値が不明なため、ivdep ではベクトル化を行いません (ベクトル化は k<0 の場合、不正です )。

ivdep ディレクティブの例

#pragma ivdep

 

for(i=0; i<m; i++)

{

   a[i]=a[i+k]*c;

}

vector aligned ディレクティブ

vector aligned ディレクティブは、ループのベクトル化が可能である限り、ベクトル化によるメリットの存否についての通常のヒューリスティックな判断を無視してベクトル化を行います。aligned または unaligned 指示子が使用されると、ループは、aligned または unaligned 演算を使用して、ベクトル化されます。aligned または unaligned のいずれか 1 つを指定します。

警告

引数として aligned を指定する場合、ループはこの命令を使用してベクトル化可能であることが確実でなければなりません。それ以外の場合、コンパイラは誤ったコードを生成します。次の例に示すループは、コンパイラは通常それが安全であると証明できないように配列が宣言されているため、aligned 指示子を使用して、aligned 命令でループがベクトル化されるように要求を出します。

vector aligned ディレクティブの例

#void foo(float *a)

{

   #pragma vector aligned

   for(i=0; i<m; i++)

   {

      a[i]=a[i]*c;

   }

}

コンパイラは、コンパイル時にデータ構造のアライメントがわからない場合に備えて、いくつかのアライメント手法を持っています。以下に簡単な例を次に示します (但し、他の方法もサポートされています)。次の例のループにおいて、a のアライメントが不明な場合、コンパイラはプレリュードのループを生成し、ほとんどの場合に発生する配列参照がアライメントされたアドレスにヒットするまでループを繰返します。これにより、a のアライメント・プロパティが判明し、そのプロパティに応じてベクトルループが最適化されます。

アライメント手法の例

float *a;

 

//Alignment unknown

for(i=0; i<100; i++)

{

   a[i]=a[i]+1.0f;

}

 

//Dynamic loop peeling

p=a & 0x0f;

if(p!=0)

{

   p=(16-p)/4;

   for(i=0; i<p; i++)

   {

      a[i]=a[i]+1.0f;

   }

}

 

//Loop with a aligned.

//Will be vectorized accordingly.

for(i=p; i<100; i++)

{

   a[i]=a[i]+1.0f;

}

novector ディレクティブ

novector ディレクティブは、ループのベクトル化が有効であっても、ベクトル化を行わないよう指定します。この例では、反復回数 (ub - lb) が低すぎて、ベクトル化が無駄になるとわかっています。novector を使用して、ループがベクトル化可能であると認識されても、コンパイラにベクトル化しないように指示できます。

novector ディレクティブの例

void foo(int lb, int ub)

{

   #pragma novector

   for(j=lb; j<ub; j++)

   {

      a[j]=a[j]+b[j];

   }

}