2

Open MP APIをテストするために、少しサンプルコードを作成したいと思います。これで計算を使って3レベルのForループを作成しました。

問題は、私の結果が間違っていることです。

これが私のコードです:

long value = 0;
#pragma omp parallel
{
#pragma omp for
for (int i=0;i<=9999;i++)
{
    value += (M_PI * i * i -12,33 * M_PI)- M_PI;

    for (int j=0;j<=888;j++)
    {
        value += (M_PI * j * i -12,33 * M_PI)- M_PI;

        for (int k=0;k<=777;k++)
        {
            value += (M_PI * k * j -12,33 * M_PI)- M_PI;    
        }
    }
}
}    

私の問題 :

Open MPがない場合、value変数の値は次のようになります191773766 。Whit Open MPの場合、value変数の値は次 のようになります。1092397966

これは同期の問題だと思いますが、これを解決するにはどうすればよいですか?私はOpenMPについてたくさん読んだことがありますが、それを解決する方法がわかりません。

どうもありがとう、

よろしくお願いします、

4

1 に答える 1

7

reduction(+:value)句がありません。

#pragma omp parallel reduction(+:value)  //  add reduction here
{
#pragma omp for

これが必要な理由は、value変数をすべてのスレッドで共有しているためです。そのため、競合状態につながる非同期に更新します。(キャッシュの一貫性からもパフォーマンス ヒットが発生します。)

このreduction(+:value)句は、valueスレッドごとに個別のインスタンスを作成し、最後にそれらを合計するようにコンパイルに指示します。


編集: OP の要求に応じて完全なコード。

int main() {

    double start = omp_get_wtime();

    long M_PI = 12;

    long value = 0;
#pragma omp parallel reduction(+:value)
{
#pragma omp for
for (int i=0;i<=9999;i++)
{
    value += (M_PI * i * i -12,33 * M_PI)- M_PI;

    for (int j=0;j<=888;j++)
    {
        value += (M_PI * j * i -12,33 * M_PI)- M_PI;

        for (int k=0;k<=777;k++)
        {
            value += (M_PI * k * j -12,33 * M_PI)- M_PI;    
        }
    }
}
}    
    double end = omp_get_wtime();
    printf("\n\nseconds = %f\n",end - start);

    cout << value << endl;

    system("pause");
    return 0;
}

出力: (OpenMP なし)

seconds = 0.007816
738123776

出力: (OpenMP を使用 - 8 スレッド)

seconds = 0.012784
738123776

スピードアップが必要な場合は、タスクをはるかに大きくする必要があります。

于 2012-06-18T20:56:57.193 に答える