- 締切済み
CUDAにおける排他的処理について
CUDAにおいて異なるBlockがグローバルメモリの配列に加算を行う場合を考えます。 配列の同じアドレスに異なるBlockのThreadが加算処理を行う際は競合を避けるためにatomicAdd()を用いるのが一般的ですが、atomicAdd()を用いると処理が逐次的になってしまいパフォーマンスが低下します。 このような場合にもっと効率の良い方法はないでしょうか(atomicAdd()を使わないような)? どなたか教えていただけると幸いです。
- みんなの回答 (1)
- 専門家の回答
みんなの回答
- unokwave
- ベストアンサー率58% (966/1654)
回答No.1
何故逐次処理になるのかを理解していますか? 排他制御のうち書き込み用排他制御は並列処理できないからです。 効率を上げたければ1要素ごとではなくブロック単位で、そのブロックも他との並列性が損なわれない範囲で大きくする事が効率化に繋がります。 CUDAを弄っていたのは10年ほど前なので直接的なアドバイスはできませんが、グローバルメモリをエリアで所有権を確保する手続きを呼び出し元との間で行うか、グローバルメモリの内容をコピーして加算後に書きもどすかするしかないでしょう。 グローバルメモリをエリアで所有権を確保するには、グローバルメモリ上の任意のアドレスの変数をatomicInc等を利用して排他制御用変数として扱い、自作の排他制御関数を作る必要があるかも知れません。 そのエリアを書き換えたい側がその関数を呼び、結果が1であれば書き込み許可、1でなければ待機、という仕様として、その関数ではatomicIncの結果が1でなければatomicDecを呼んでから1以外を返します。 それをそのエリアを利用したいGPU側もCPU側も行います。