次のような新しいケプラーのシャッフル命令を使用して、CUDA で並列削減の実装を使用しています: http://devblogs.nvidia.com/parallelforall/faster-parallel-reductions-kepler/
特定の行列の行の最小値を検索していたところ、カーネルの最後に次のコードがありました。
my_register = min(my_register, __shfl_down(my_register,8,16));
my_register = min(my_register, __shfl_down(my_register,4,16));
my_register = min(my_register, __shfl_down(my_register,2,16));
my_register = min(my_register, __shfl_down(my_register,1,16));
私のブロックは 16*16 であるため、すべてが正常に機能し、そのコードを使用して、まったく同じカーネルの 2 つのサブ行で最小値を取得していました。
ここで、マトリックスのすべての行の最小要素のインデックスも返す必要があるため、「min」を「if」ステートメントに置き換えて、これらのインデックスを同様の方法で処理するつもりでしたが、次のコードで行き詰まりました。
if (my_reg > __shfl_down(my_reg,8,16)){my_reg = __shfl_down(my_reg,8,16);};
if (my_reg > __shfl_down(my_reg,4,16)){my_reg = __shfl_down(my_reg,4,16);};
if (my_reg > __shfl_down(my_reg,2,16)){my_reg = __shfl_down(my_reg,2,16);};
if (my_reg > __shfl_down(my_reg,1,16)){my_reg = __shfl_down(my_reg,1,16);};
cudaErrors はまったくありませんが、カーネルは現在ゴミを返します。それにもかかわらず、私はそれを修正しました:
myreg_tmp = __shfl_down(myreg,8,16);
if (myreg > myreg_tmp){myreg = myreg_tmp;};
myreg_tmp = __shfl_down(myreg,4,16);
if (myreg > myreg_tmp){myreg = myreg_tmp;};
myreg_tmp = __shfl_down(myreg,2,16);
if (myreg > myreg_tmp){myreg = myreg_tmp;};
myreg_tmp = __shfl_down(myreg,1,16);
if (myreg > myreg_tmp){myreg = myreg_tmp;};
したがって、新しい tmp 変数を割り当てて隣接するレジスタに忍び込ませると、すべてが節約されます。ここで質問です: ケプラー シャッフル命令は破壊的ですか? 同じ命令を 2 回呼び出しても同じ結果は得られないという意味で。「my_reg > __shfl_down(my_reg,8,16)」と言ってこれらのレジスタに何も割り当てていません - これは私の混乱を招きます。シャッフルを2回呼び出すことの問題は何ですか?私はCUDAの初心者なので、ダミーの詳細な説明を歓迎します