4

高速に実行したいコードがいくつかあるので、gcc (g++) を説得して内部ループの一部をベクトル化できることを期待していました。私のコンパイラフラグには以下が含まれます

-O3 -msse2 -ffast-math -ftree-vectorize -ftree-vectorizer-verbose=5

しかし、gcc は最も重要なループのベクトル化に失敗し、次のようなあまり詳細ではないメッセージが表示されます。

Not vectorized: complicated access pattern.

Not vectorized: unsupported use in stmt.

私の質問は(1)これらは正確には何を意味するのですか?(複雑になりすぎる前に、どのくらい複雑にする必要がありますか?サポートされていない使用方法は正確に?)、(2) コンパイラーに、私がやっていることについてほんの少しでも多くの情報を提供してもらう方法はありますか?違う?

「複雑なアクセス パターン」を与えるループの例は次のとおりです。

for (int s=0;s<N;++s)
    a.grid[s][0][h-1] =  D[s] * (b.grid[s][0][h-2] + b.grid[s][1][h-1] - 2*b.grid[s][0][h-1]);

そして、「サポートされていない stmt での使用」を与えるものは、の内側のループです。

for (int s=0;s<N;++s)
    for (int i=1;i<w-1;++i) 
        for (int j=1;j<h-1;++j) 
            a.grid[s][i][j] = D[s] * (b.grid[s][i][j-1] + b.grid[s][i][j+1] + b.grid[s][i-1][j] + b.grid[s][i+1][j] - 4*b.grid[s][i][j]);

(これは本当に最適化する必要があるものです。) ここで、a.grid と b.grid は float の 3 次元配列、D は float の 1D 配列、N、w、h は const int です。

4

1 に答える 1

3

ベクトル化されていない: 複雑なアクセス パターン。

「単純な」アクセス パターンは、特定の制限 (ループ内でアクセスされるグループの単一要素、グループ要素数が 2 の累乗、グループ サイズがベクター型の倍数) を伴う、連続した要素アクセスまたはストライド要素アクセスです。

b.grid[s][0][h-2] + b.grid[s][1][h-1] - 2*b.grid[s][0][h-1]);

シーケンシャルアクセスでもストライドアクセスでもない

ベクトル化されていません: stmt での使用はサポートされていません。

ここでの「使用」はデータフローの意味であり、変数の値を取得します (レジスター、一時的なコンパイラー)。この場合、「サポートされる用途」は、ループの現在の反復で定義された変数、定数、およびループ不変条件です。

a.grid[s][i][j] = D[s] * (b.grid[s][i][j-1] + b.grid[s][i][j+1] + b.grid[s][i-1][j] + b.grid[s][i+1][j] - 4*b.grid[s][i][j]);

b.grid[s][i][j-1]この例では、「サポートされていない使用」は、ループの前の繰り返しによってとb.grid[s][i][j+1]が割り当てられている (「定義されている」)ためだと思います。

于 2012-11-22T10:01:39.063 に答える