6

プログラムの実行に沿ってある種の合計を計算するために、共有変数、たとえばdoubleを使用する場合。それはとにかく不安定な操作に対して脆弱でしょうか?つまり、複数のコアが非同期でこの変数にアクセスし、不安定な結果を引き起こす可能性がありますか?

例:これはグローバル変数です:

double totalTime = 0;

各コアでコマンドが呼び出されます。

totalTime += elapsedTime;

この最後の操作/ステートメントは、totalTimeの値を取得し、それをCPUレジスターに入れてから、加算を実行することによって実行されます。複数のコアが同時に同じ値を取り、新しい経過時間を追加すると、レイテンシーのために、totalTimeに格納されている値が間違った値で上書きされることが想像できます。それは可能ですか?どうすればこれを解決できますか?

ありがとうございました。

4

1 に答える 1

5

あなたがあなた自身に述べたように、それはいくつかのアセンブラ命令を含むので、明らかにこの操作はスレッドセーフではありません。実際、openMPには、この種の操作のための特別なディレクティブさえあります。

atomicそれを「アトミック」にするためのプラグマが必要になります。

#pragma omp atomic
totalTime += elapsedTime;

atomic加算、増分など、メモリ位置を1回更新した場合にのみ機能することに注意してください。

一緒にアトミックにする必要がある一連の命令がある場合は、criticalディレクティブを使用する必要があります。

#pragma omp critical
{
    // atomic sequence of instructions
}

編集:「snemarch」からの良い提案です:totalTime並列ループでグローバル変数を繰り返し更新している場合は、このreduction句を使用してプロセスを自動化し、さらに効率的にすることを検討できます。

double totalTime = 0;

#pragma omp parallel for reduction(+:totalTime)
for(...)
{
    ...
    totalTime += elapsedTime;
}

最後に、明示的な同期を必要とせずtotalTimeに、ローカル値の合計が正しく含まれます。elapsedTime

于 2012-06-11T10:05:42.513 に答える