3

メモリ内の1つの場所に同じ値を書き込もうとしているスレッドが複数ある場合、競合状態になる可能性はありますか?書き込み中にデータが何らかの形で破損する可能性はありますか?先行する読み取りまたはテスト条件はなく、書き込みのみです。

編集:明確にするために、私はGPUでドット積を計算しています。複数のスレッドを使用して個々の製品を計算し(行/列要素ごとに1つのスレッド)、それらをメモリ内の一時的な場所に保存しています。次に、それらの中間製品を合計して結果を保存する必要があります。

GPUで分岐するとパフォーマンスが低下する可能性があるため、すべてのスレッドでこの合計/ストア操作を個別に実行することを考えていました。(単一のスレッドで実行された場合でも、すべてのスレッドで実行された場合でも、合計/ストアに同じ時間がかかると思いますが、これをテストしたところ、パフォーマンスにわずかな影響があります。)すべてのスレッドで同じ合計が得られます。 、しかし、それぞれがメモリ内の同じ場所に回答を書き込もうとする場合の競合状態が心配です。私が行った限られたテストでは、すべてがうまくいくように見えますが、私はまだ緊張しています...

4

4 に答える 4

4

ほとんどのプラットフォームのほとんどのスレッド標準では、これは単に禁止されているか、定義されていません。つまり、それを行うことは許可されておらず、そうすると、何かが起こる可能性があります。

CやC++用の高級言語コンパイラーは、許可されていないことは何もしないという仮定に基づいて、コードを自由に最適化できます。したがって、「書き込み専用」操作はそのようなことではないことが判明する場合があります。CまたはC++で記述した場合i = 1;、コンパイラーは、を記述した場合と同じコードを自由に生成できますi = 0; i++;。同様に、交絡最適化は実際に現実の世界で発生します。

代わりに、適切な同期プリミティブを使用するために使用しているスレッドモデルのルールに従ってください。プラットフォームがそれらを提供する場合は、適切な不可分操作を使用してください。

于 2012-11-14T17:22:25.763 に答える
2

一見、答えはノーのように見えますが、競合状態はなく、答えはもう少し微妙です。Borisは、一部の32ビットアーキテクチャでは、64ビット長またはアドレスの格納に2つの操作が必要になる可能性があるため、無効な状態で読み取られる可能性があることは正しいです。メモリページは通常更新されるものであり、長いメモリページにまたがることはないため、これを再現するのはおそらくかなり困難です。

ただし、より重要な問題は、メモリの同期がないと、スレッドが更新された値をいつ表示するかについての保証がないことを理解する必要があるということです。スレッドは、メモリから古い値を読み取るために長期間実行される可能性があります。無効な値ではありませんが、最後に書き込まれた値ではありません。これは特に「競合状態」を引き起こすわけではありませんが、プログラムが予期しない方法で実行される可能性があります。

また、「書き込み専用」と言っても、明らかに誰かが値を読み取っています。そうでない場合、更新を実行する理由はありません。コードのどの部分が値を読み取っているのかという詳細は、同期なしの書き込み専用が本当に安全であるかどうかについて、より適切に通知します。

于 2012-11-14T17:24:21.923 に答える
2

複数のスレッドがCUDAに単一の(おそらく共有またはグローバルな)メモリ位置を書き込む場合でも、「同時に」、つまり同じコード行からでも問題はありません。

書き込みの順序を気にする場合、CUDAは順序を保証しないため、同じメモリ位置に対して同じ書き込み操作を実行する複数のスレッドに対して、これは問題になります。これが問題になる場合は、アトミックまたはコードをリファクタリングする他の方法を使用してコードを整理する必要があります。(これはあなたにとって問題ではないようです。)

おそらく、別のレスポンダーが述べているように、あなたはある時点で結果を気にします。したがって、明示的(たとえば、共有メモリを使用するブロック内の複数のスレッドの場合は__synchthreads())または暗黙的(たとえば、カーネルの終わり、グローバルメモリ内の場所に書き込む複数のスレッドの場合)のいずれかの何らかのバリアが必要です。 )その場所を読んで、賢明な結果を期待する前に。正しい結果をもたらす可能性のあるバリア方法はこれらだけではなく、2つの例にすぎないことに注意してください。ワープ同期動作またはその他の巧妙なコーディング手法を活用して、書き込みのコレクションに続く読み取りの健全性を確保できます。

于 2012-11-16T16:18:58.200 に答える
1

書き込み専用操作が明らかにアトミックでない場合、別のスレッドが破損した状態のデータを監視する可能性がある瞬間があります。

たとえば、32ビット整数のペアとして格納されている64ビット整数への書き込み。

スレッドA-上位ワードの書き込みが終了し、スレッドBは下位ワードへの書き込みが終了し、上位ワードを設定します。

スレッドCは、整数がスレッドBによって書き込まれた下位ワードとスレッドAによって書き込まれた上位ワードで構成されていることを確認できます。

PSこの質問は非常に一般的であり、実際の結果は、環境(言語)のメモリモデルと基盤となるプロセッサアーキテクチャ(ハードウェア)によって異なります。

于 2012-11-14T17:15:24.440 に答える