これは、CUDA でリダクションを実行する通常の方法です。
各ブロック内で、
1) 各スレッドの共有メモリに現在の縮小値を保持します。したがって、各スレッドはグローバルメモリから n (個人的には 16 から 32 の間が好きです) の値を読み取り、これらから削減された値を更新します。
2) ブロック内で縮小アルゴリズムを実行して、ブロックごとに 1 つの最終縮小値を取得します。
この方法では、(スレッド数) * sizeof (dataty) バイトより多くの共有メモリは必要ありません。
各ブロックは減らされた値であるため、最終値を取得するには 2 回目の減縮パスを実行する必要があります。
たとえば、ブロックごとに 256 のスレッドを起動し、スレッドごとに 16 の値を読み取る場合、ブロックごとに (256 * 16 = 4096) 要素を減らすことができます。
したがって、100 万個の要素がある場合、最初のパスで約 250 ブロックを起動する必要があり、2 回目で 1 ブロックだけ起動する必要があります。
この構成で要素数 > (4096)^2 の場合は、おそらく 3 番目のパスが必要になります。
グローバル メモリの読み取りが結合されるように注意する必要があります。グローバル メモリの書き込みを結合することはできませんが、これはパフォーマンス ヒットの 1 つです。