一意のブロックインデックスを必要とし、3Dグリッド全体でスケーリングできるように、可能な限りスケーリングする必要があるカーネルがあるとします。
計算はかなり複雑に見えます。1つのスレッドだけで計算を実行し、共有メモリに保存します。それは良い考えですか?
すべての文献で、常にレジスタに格納されていますが、共有メモリの欠点は何ですか?
よくわかりませんが、レジスタが1サイクルであるのに対し、共有メモリの読み取り/書き込みアクセスは4サイクルですか?
それ以外の:
__global__ kernel()
{
//get unique 3D block index
const unsigned long long int blockId = blockIdx.x //1D
+ blockIdx.y * gridDim.x //2D
+ gridDim.x * gridDim.y * blockIdx.z; //3D
}
多分使用:(ブロックのx次元のみが使用されると仮定)
__global__ kernel()
{
__shared__ unsigned long long int blockId_s;
if(threadIdx.x == 0)
blockId_s = blockIdx.x //1D
+ blockIdx.y * gridDim.x //2D
+ gridDim.x * gridDim.y * blockIdx.z; //3D
__syncthreads();
}
これにより、スレッドごとに1つのレジスタが節約され、コンピューティング機能1.xではコストがかかります。
私にはテストがなく、パフォーマンスに良いか悪いかわかりません。__syncthreads()
cc 1.xで使用可能なもう1つのレジスタは引数ですが、ステートメントを使用するとパフォーマンスが少し遅くなるはずです。