2

次のように、小さなコードのスピードアップをテストしようとしています。

for(i=0;i<imgDim;i++)
        {
            X[0][i] = Z[i] - U1[i] * rhoinv;
            X[1][i] = Z[i] - U2[i] * rhoinv;
            X[2][i] = Z[i] - U3[i] * rhoinv;
        }

反復は約 200 回で、imgDim は 1000000 です。このコードの合計時間は約 2 秒です。コード全体のコストは約 15 秒です。しかし、openmp を使用してこのコードを次のように並列化した後:

omp_set_num_threads(max_threads);
    #pragma omp parallel shared(X,Z,U1,U2,U3,imgDim,rhoinv) private(i) 
    {
        #pragma omp for schedule(dynamic)
        for(i=0;i<imgDim;i++)
        {
            X[0][i] = Z[i] - U1[i] * rhoinv;
            X[1][i] = Z[i] - U2[i] * rhoinv;
            X[2][i] = Z[i] - U3[i] * rhoinv;
        }
    }

max_threads は 8 です。コードのこの小さな部分だけで約 11 秒かかり、コード全体で約 27 秒かかります。最も奇妙なことは、max_threads を 1 に変更すると、時間が 6 秒に短縮されることです。それでも、シーケンシャル コードよりもはるかに長くなります。

それは私に多くの時間を要し、私は問題を見つけることができません。誰かが私を助けてくれれば、深く感謝します。

4

1 に答える 1

3

schedule(dynamic)実行時のオーバーヘッドが非常に大きくなります。各繰り返しにかかる時間が異なり、負荷分散の改善によりオーバーヘッドが正当化されるループにのみ使用してください。あなたのような定期的なループの場合、動的スケジューリングは不要なオーバーヘッドが発生し、計算が遅くなるためやり過ぎです。

スケジュール タイプを次のように変更しstaticます。

#pragma omp parallel for schedule(static) 
for(i=0;i<imgDim;i++)
{
    X[0][i] = Z[i] - U1[i] * rhoinv;
    X[1][i] = Z[i] - U2[i] * rhoinv;
    X[2][i] = Z[i] - U3[i] * rhoinv;
}

(注: 外側のスコープで宣言された変数はデフォルトで共有され、並列ループ制御変数は暗黙的にプライベートです)

于 2013-02-07T11:54:44.357 に答える