3

私の質問の簡単な背景として、x86を使用すると、32ビットワードの場合は4バイトにアラインされた、または64ビットワードの場合は8バイトにアラインされた個々のメモリアクセスがアトミックになることが保証されます。したがって、「良性のデータ競合」を作成できます。この場合、少なくとも1つのスレッドがメモリアドレスに書き込み、別のスレッドが同じアドレスから読み取ります。リーダーは、不完全な書き込みの結果を確認できません。読み取りスレッドは書き込みの全体的な効果を確認するか、確認しません。

これらのタイプの「良性」データ競合状態を作成するためのCUDAプログラミングモデルの要件は何ですか?たとえば、2つの別々のスレッドが2つの別々のSMから同じグローバルメモリアドレスに64ビット値を書き込む場合、2つの異なるSMで同時に実行されているブロックは、それぞれ64ビット値全体をアトミックに書き込みます。3番目のオブザーバーは読み取りのみを行います。完全に更新された64ビットメモリブロック?または、書き込みはより小さな粒度で行われるので、3番目のオブザーバーは、2つのスレッドが同時に書き込みを行った後にメモリアドレスから読み戻そうとした場合にのみ、部分的な書き込みを確認しますか?

競合状態は通常避けるべきものであることを理解していますが、メモリオーダリングの要件が緩和されている場合は、アトミック読み取り/書き込み関数を明示的に使用する必要はありません。そうは言っても、これは個々の読み取り/書き込みのアトミック性(つまり、ビット数とアラインメント)に基づいています。誰かが私がこの情報を見つけることができる場所を知っていますか?

4

1 に答える 1

1

更新:@Heatsinkから、__threadfence()関数を使用してメモリの一貫性を強制することが実際に可能であることが通知されました。

-

アトミック関数が使用されない限り、CUDAは、同じカーネル呼び出しでスケジュールされたスレッドによって更新されたグローバルメモリにアクセスするときに、一貫性を特に保証しません。以前のカーネルまたはメモリコピーによって書き込まれたメモリを読み取ることのみが安全です。

したがって、メモリアクセスパターンについて何も想定できないだけでなく、あるスレッドによってグローバルメモリに対して行われた更新がいつ別のスレッドに表示されるか、または実際に表示されるかどうかさえわかりません。

もちろん、特定のアーキテクチャでハードウェアを実装する方法を考えると、スレッド間にある種のノンブロッキング同期を実装する方法を見つけることができるかもしれません。しかし、ブロック間で安全にそれができるのではないかと心から疑っています。1つのブロック内のスレッドに表示される内容は、ブロックが実行されているSM、以前に実行されたブロック、およびそれらのブロックによって実行された更新が現在キャッシュ階層のどこにあるかによって異なります。

ブロック内のスレッドを検討する場合、ブロック内のスレッドは共有メモリと通信でき、その動作はCUDAによって慎重に指定されているため、議論は議論の余地があります。

于 2012-06-29T19:25:39.813 に答える