1. ホーム
  2. cuda

[解決済み] CUDAにおけるメモリ合体とは何ですか?

2023-06-26 07:11:04

質問

CUDAのグローバルメモリトランザクションで、quot;coalesced"とは何でしょうか。CUDAのガイドを読んでもよくわかりませんでした。どうすればいいのでしょうか?CUDAプログラミングガイドの行列の例で、行列の行ごとにアクセスすることを"coalesced"といい、col.ごとにアクセスすることをcoalescedといいますが、どちらが正しいのでしょうか? どちらが正しいですか、またその理由は?

どのように解決するのですか?

この情報は、compute capabality 1.x または cuda 2.0 にのみ適用される可能性があります。最近のアーキテクチャおよび cuda 3.0 は、より洗練されたグローバル メモリ アクセスを備えており、実際、これらのチップでは合体グローバル負荷はプロファイリングさえされていません。

また、このロジックはバンクの競合を回避するために共有メモリに適用することができます。


coalesced memory transaction は、ハーフワープ内のすべてのスレッドが同時にグローバルメモリにアクセスするものです。これは単純すぎますが、正しい方法は、連続したスレッドが連続したメモリ アドレスにアクセスするだけです。

つまり、スレッド 0、1、2、3 がグローバル メモリ 0x0、0x4、0x8、0xc を読み込む場合、それは coalesced リードであるべきです。

行列の例では、行列がメモリ内に線形に存在するようにすることに留意してください。これはどのようにでも行うことができ、メモリ アクセスは行列がどのようにレイアウトされるかを反映する必要があります。つまり、以下の 3x4 の行列は

0 1 2 3
4 5 6 7
8 9 a b

は、次のように、行の後に行うことができ、 (r,c) はメモリ (r*4 + c) に対応するようになります。

0 1 2 3 4 5 6 7 8 9 a b

要素に一度だけアクセスする必要があり、4つのスレッドがあるとします。どのスレッドがどの要素に使われるのでしょうか?おそらく

thread 0:  0, 1, 2
thread 1:  3, 4, 5
thread 2:  6, 7, 8
thread 3:  9, a, b

または

thread 0:  0, 4, 8
thread 1:  1, 5, 9
thread 2:  2, 6, a
thread 3:  3, 7, b

どちらがよいのでしょうか?どちらがコアレスリードになり、どちらがならないのでしょうか?

いずれにせよ、各スレッドは3回アクセスします。最初のアクセスを見て、スレッドが連続してメモリにアクセスするかどうかを確認しましょう。最初の選択肢では、最初のアクセスは 0, 3, 6, 9 です。連続でも合体でもありません。2番目のオプションでは、0, 1, 2, 3です。連続! Coalesced! やったー!

最良の方法は、おそらくカーネルを書き、それをプロファイルして、グローバルロードとストアが非合理化されているかどうかを確認することでしょう。