1

最近、プログラムをマルチスレッド化する方法を学ぶために、Visual Studio で OpenMP を試してみました。

このコードをシリアルに実行しようとすると:

int totalSum = 0;

for(int x=0; x < 100; x++)
{
    for(int y=0; y < 100; y++)
    {
        totalSum = totalSum + x + y;
    }
}  

最終的には、totalSum = 990000になります

次のように言って OpenMP 機能を追加しようとすると、

#pragma omp parallel for
    for(int x=0; x < 100; x++)
    {

        for(int y=0; y < 100; y++)
        {
            totalSum = totalSum + x + y;
        }
    }

最終的にtotalSum = 491293または 596865 または 638260 などになります...

明らかに何が起こっているかというと、競合状態が発生しているように見え、どのスレッドが最初に totalSum にアクセスするかによって、最終的な答えが異なります。

私は間違って何をしていますか? x と y はプライベート変数として正しく定義されています (並列領域内で作成されるため)。

プログラムをマルチスレッド化しているときと、シリアルで実行しているときとで同じ答えが得られるようにするにはどうすればよいですか?

4

1 に答える 1

2

修正は、次のreduction句を使用することです。

int totalSum = 0;

#pragma omp parallel for reduction(+:totalSum)  //  reduction
for(int x=0; x < 100; x++)
{

    for(int y=0; y < 100; y++)
    {
        totalSum = totalSum + x + y;
    }
}

OpenMP 削減条項を読んで、それがどのように機能するかを理解してください。

于 2012-11-09T04:07:20.777 に答える