ベクトル化レポート

ベクトル化レポートは、IA-32 アーキテクチャー・ベース・システムおよびインテル(R) 64 アーキテクチャー・ベース・システムで利用でき、SSE3、SSE2、SSE のベクトル化を活用できるループについての情報を提供します。

その他のベクトル化のオプションについては、「並列化の使用」を参照してください。

-vec-report (Linux* および Mac OS* X) または /Qvec-report (Windows*) オプションは、異なるレベルの情報を含むベクトル化レポートを生成するようにコンパイラーに指示します。値に 3 を指定して、詳細な診断レポートを生成します。

プラットフォーム

コマンド

Linux および Mac OS X

icpc -c -xT -vec-report3 sample.cpp

Windows

icl /c /QxT /Qvec-report:3 sample.cpp

-c (Linux および Mac OS X) または /c (Windows) は、実行ファイルを生成しないでサンプルコードをコンパイルするようにコンパイラーに指示します。

Linux および Mac OS X: オプションとフェーズの間のスペースはオプションです。
Windows: オプションとフェーズの間のコロンはオプションです。

次に、ベクトル化レポートによって生成される結果の例を示します。

結果の例

sample.cpp(10) : (col. 2) remark: ループはベクトル化されませんでした。: 内部ループではありません。

sample.cpp(11) : (col. 6) remark: ループはベクトル化されませんでした。: 内部ループではありません。

sample.cpp(12) : (col. 5) remark: ベクトル依存関係: FLOW の依存関係が c 行 13 と b 行 13 の間に仮定されました。

sample.cpp(12) : (col. 5) remark: ベクトル依存関係: FLOW の依存関係が c 行 13 と a 行 13 の間に仮定されました。

sample.cpp(12) : (col. 5) remark: ベクトル依存関係: FLOW の依存関係が c 行 13 と c 行 13 の間に仮定されました。

sample.cpp(12) : (col. 5) remark: ループはベクトル化されませんでした。: ベクトル依存関係が存在しています。

ベクトル依存が存在するために、コンパイラーが "ループはベクトル化されませんでした" とレポートした場合、ループのベクトル依存解析を行う必要があります。ベクトル依存が存在しないことがわかっている場合、上記のメッセージは、コンパイラーがループ中のポインターまたは配列が依存していると仮定したことを示し、ポインターまたは配列がエイリアスされたことをに示します。メモリーの一義化テクニックを使用してこの問題を解決します。

主なベクトル依存は、FLOWANTI、および OUTPUT の 3 つです。

ベクトル依存が有効かどうかを判断するには、「ループの独立性」を参照してください。コンパイラー・レポートは、何もないところでベクトル依存があると報告することがあります。これは、コンパイラーがメモリー・エイリアシングを仮定するためです。このような場合には、コードの依存性を確認してください。コードの依存性がない場合には、メモリー・エイリアシング (restrict または ivdep を含む) で説明されている手法を使用してコンパイラーに知らせます。

ベクトル化レポートは、さまざまな状況でベクトル依存を示します。以下のような状況で、非ユニットストライド、低いトリップカウント、複雑な添字式がベクトル依存としてレポートされることがあります。

非ユニットストライド

メモリーが非ユニットストライド方式でアクセスされたときに、ループがベクトル化できなかったことがレポートで示されることがあります。これは、ループで連続していないメモリーの場所がアクセスされていることを意味します。この場合、ループ交換で問題が解決できないか確認してください。解決できない場合、vector always プラグマによってベクトル化するように指定します。この際、状況が改善されたかを確認してください。

非ユニットストライド条件に関する詳細は、「ランタイム・パフォーマンスの理解」を参照してください。

その他のオプションの使用方法

ベクトル化レポートは、実行ファイルが生成される最後のコンパイルフェーズで生成されます。したがって、レポートを生成する場合に使用できないオプションの組み合わせがあります。次のオプションの組み合わせを使用した場合、コンパイラーは警告を表示してレポートを生成しません。

次のコマンド例は、ベクトル化レポートを生成できます。

プラットフォーム

コマンド例

Linux および Mac OS X

次のコマンドは、ベクトル化レポートを生成します。

icpc -xK -vec-report3 sample.cpp

icpc -xK -ipo -vec-report3 sample.cpp

icpc -c -xK -ipo -vec-report3 sample.cpp

次のコマンドは、ベクトル化レポートを生成しません。

icpc -c -xK -vec-report3 sample.cpp

icpc -xK -ipo -vec-report3 sample.cpp

icpc -c -xK -ipo -vec-report3 sample.cpp

Windows

次のコマンドは、ベクトル化レポートを生成します。

icl /QxK /Qvec-report:3 sample.cpp

icl /QxK /Qipo /Qvec-report:3 sample.cpp

icl /c /QxK /Qipo /Qvec-report:3 sample.cpp

次のコマンドは、ベクトル化レポートを生成しません。

icl /c /QxK /Qvec-report:3 sample.cpp

icl /QxK /Qipo /Qvec-report:3 sample.cpp

icl /c /QxK /Qipo /Qvec-report:3 sample.cpp

関連情報

対応

以下の条件でベクトル化できるようにするには、既存のコードを変更する必要があります。

例えば、同一の出力を行う 2 つの同等なアルゴリズムを考えます。"foo" はフロー依存のためにベクトル化されませんが、"bar" はベクトル化されます。

void foo(double *y)

{

  for(int i=1;i<10;i++) {

  // a loop that puts sequential numbers into array y

    y[i] = y[i-1]+1;

  }

}

void bar(double *y)

{

  for(int i=1;i<10;i++) {

  // a loop that puts sequential numbers into array y

    y[i] = y[0]+i;

  }

}

サポートされていないループ構造はベクトル化できません。サポートされていないループ構造の例は、複雑な計算が必要なループ・インデックス変数です。構造を変更して、ループ制限への関数呼び出しおよびループ制限に対するその他の過度な計算を削除します。

int function(int n)

{

  return (n*n-1);

}

void unsupported_loop_structure(double *y, int n)

{

  for (int i=0; i<function(n); i++) {

    *y = *y * 2.0;

  }

}

非ユニット・ストライド・アクセスは、ベクトル化レポートで "ループはベクトル化されませんでした: ベクトル化は可能ですが非効率です" のように示されます。ユニットストライド方式でデータにアクセスするようにループを再構成 (例えば、ループ交換を適用) するか、またはプラグマ vector always を使用します。

ループの中で混在データ型を使用するとベクトル化できません。混在データ型の場合、ベクトル化レポートで "ループはベクトル化されませんでした: 条件が複雑すぎます" のように示されます。

次に、ループ内に混在データ型が使用されているためにベクトル化できないループの例を示します。例えば、withinborder は整数ですが、ループの他のすべてのデータ型は整数ではありません。withinborder のデータ型を変更することで、このループをベクトル化できます。

int howmany_close(double *x, double *y)

{

  int withinborder=0;

  double dist;

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

    dist=sqrtf(x[i]*x[i] + y[i]*y[i]);

    if (dist<5) withinborder++;

  }

  return 0;

}