假设我们有一个内核,它需要一个唯一的块索引,并且应该尽可能地扩展,以便它应该在 3D 网格中扩展。
计算看起来很复杂,让一个线程执行它并将其存储在共享内存中。这是个好主意吗?
在所有文献中它总是存储在寄存器中,但是共享内存的缺点是什么?
我不确定,但共享内存读写访问是 4 个周期,而寄存器是 1 个周期?
代替:
__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.x 中是昂贵的。
我没有测试,也不知道它对性能是好是坏。__syncthreads()
cc 1.x 上的另一个可用寄存器是一个参数,但使用语句时性能应该会慢一些。