2

クラスでは、ベクトル化することになっていた単純なループが与えられました。これで十分うまくいきましたが、奇妙なことに遭遇しました。次のコードを検討してください。

#include<stdio.h>

void func(int N, double *a, double *b, double *c, double *d) {
  int i;
  #pragma ivdep
  for ( i=0; i<N; i++ ) {
    d[i] = c[i+1];
  }
  #pragma ivdep
  for ( i=0; i<N; i++ ) {
    a[i] = b[i];
    c[i] = a[i] + b[i];
  }
}

これは ICC の出力です (コマンドicc -O2 -vec-report3 -c example.c、バージョン 13.0.1):

example.c(6): (col. 3) remark: LOOP WAS VECTORIZED.
example.c(6): (col. 3) remark: loop was not vectorized: not inner loop.
example.c(10): (col. 3) remark: LOOP WAS VECTORIZED.

私は-Sダンプを読むほどアセンブラに堪能ではないので、実際に何をしたのかわかりません。しかし、最初のループをベクトル化しないと推測できる理由はないので、そうすると思います

これらの矛盾したメッセージの理由は何ですか?

オープンな面では、GCC 4.5.4 (コマンドgcc -O3 -ftree-vectorizer-verbose=1 -c example.c) は両方のループをベクトル化します。一方、GCC 4.6.4 は次のように出力します。

example.c:10: note: created 3 versioning for alias checks.
example.c:10: note: LOOP VECTORIZED.
example.c:3: note: vectorized 1 loops in function.

GCC 4.8.0 はさらに冗長です。

Analyzing loop at example.c:10
Vectorizing loop at example.c:10
example.c:10: note: create runtime check for data references *_24 and *_21
example.c:10: note: create runtime check for data references *_24 and *_27
example.c:10: note: create runtime check for data references *_21 and *_27
example.c:10: note: created 3 versioning for alias checks.
example.c:10: note: === vect_do_peeling_for_loop_bound ===Setting upper bound of nb iterations for epilogue loop to 0
example.c:10: note: LOOP VECTORIZED.
Analyzing loop at example.c:6
example.c:3: note: vectorized 1 loops in function.
example.c:10: note: Turned loop into non-loop; it never loops.

どちらも最初のループについては何も述べていませんが、4.8.0 は 2 番目のループでは矛盾しているようです。

ここで何が起こっているのですか?

4

2 に答える 2

0

#pragma ivdep を削除し、次に示すように制限ポインターを導入すると、icc と gcc から同じ動作が見られます。

#include<stdio.h>

void func(int N, double *__restrict__ a, double *__restrict__ b, double *__restrict__ c, double *__restrict__ d) {
  int i;
  for ( i=0; i<N; i++ ) {
    d[i] = c[i+1];
  }
  for ( i=0; i<N; i++ ) {
    a[i] = b[i];
    c[i] = a[i] + b[i];
  }
}

icc からのベクトル化レポートは次のとおりです。

$ icc -c test.cc -vec-report2
test.cc(5): (col. 3) remark: LOOP WAS VECTORIZED
test.cc(5): (col. 3) remark: loop was not vectorized: not inner loop
test.cc(8): (col. 3) remark: LOOP WAS VECTORIZED

gcc からのベクトル化レポートは次のとおりです。

$ gcc -c -O3 -ftree-vectorizer-verbose=1 test.cc

test.cc:8: note: LOOP VECTORIZED.
test.cc:5: note: LOOP VECTORIZED.
test.cc:3: note: vectorized 2 loops in function.

ここで使用する gcc のバージョンは 4.4.4 です。restrict キーワードを指定すると、icc と gcc の両方でメモリ エイリアシング チェックが無視されます。

于 2014-05-07T17:34:18.117 に答える