みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

CUDAにおける排他的処理について

CUDAにおいて異なるBlockがグローバルメモリの配列に加算を行う場合を考えます。
配列の同じアドレスに異なるBlockのThreadが加算処理を行う際は競合を避けるためにatomicAdd()を用いるのが一般的ですが、atomicAdd()を用いると処理が逐次的になってしまいパフォーマンスが低下します。
このような場合にもっと効率の良い方法はないでしょうか(atomicAdd()を使わないような)?
どなたか教えていただけると幸いです。

投稿日時 - 2019-06-07 01:27:38

QNo.9623611

すぐに回答ほしいです

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(1)

ANo.1

何故逐次処理になるのかを理解していますか?
排他制御のうち書き込み用排他制御は並列処理できないからです。

効率を上げたければ1要素ごとではなくブロック単位で、そのブロックも他との並列性が損なわれない範囲で大きくする事が効率化に繋がります。
CUDAを弄っていたのは10年ほど前なので直接的なアドバイスはできませんが、グローバルメモリをエリアで所有権を確保する手続きを呼び出し元との間で行うか、グローバルメモリの内容をコピーして加算後に書きもどすかするしかないでしょう。

グローバルメモリをエリアで所有権を確保するには、グローバルメモリ上の任意のアドレスの変数をatomicInc等を利用して排他制御用変数として扱い、自作の排他制御関数を作る必要があるかも知れません。
そのエリアを書き換えたい側がその関数を呼び、結果が1であれば書き込み許可、1でなければ待機、という仕様として、その関数ではatomicIncの結果が1でなければatomicDecを呼んでから1以外を返します。
それをそのエリアを利用したいGPU側もCPU側も行います。

投稿日時 - 2019-06-08 13:06:11

あなたにオススメの質問