Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
cuda是否应将唯一块索引及其计算移动到共享内存?_Cuda_Synchronization_Shared Memory - Fatal编程技术网

cuda是否应将唯一块索引及其计算移动到共享内存?

cuda是否应将唯一块索引及其计算移动到共享内存?,cuda,synchronization,shared-memory,Cuda,Synchronization,Shared Memory,假设我们有一个内核,它需要一个唯一的块索引,并且应该尽可能地进行缩放,这样它就可以跨3D网格进行缩放 计算看起来相当复杂,只让一个线程执行并存储在共享内存中。这是个好主意吗? 在所有文献中,它总是存储在寄存器中,但共享内存的缺点是什么 我不确定,但共享内存读写访问是否为4个周期,而寄存器为1个周期 而不是: __global__ kernel() { //get unique 3D block index const unsigned long long int blockId

假设我们有一个内核,它需要一个唯一的块索引,并且应该尽可能地进行缩放,这样它就可以跨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维)

这将为每个线程节省一个寄存器,这在计算能力为1.x时非常昂贵

我没有测试,也不知道这对性能是好是坏。
cc 1.x上还有一个可用寄存器是一个参数,但是使用
\uu syncthreads()
语句时,性能应该会稍慢一些。

如果是共享的人,每次访问blockId时都会有n路银行冲突(n=WarpSize)。[CUDA C编程指南,5.3.2.3]


和+共享内存比寄存器慢

在这种情况下,答案是肯定的,但主要是因为生成的代码使用了更少的寄存器,这允许更高的总体占用率和一些速度。这是尽管代码在第一次扭曲中有一些分支分歧,加上一个同步原语

然而,这不应该被认为是一个通用的规则,唯一可以确保的方法是编写代码并在目标GPU上对其进行基准测试


此答案是从评论中添加的,作为社区wiki条目,以将此问题从未回答的队列中删除。

为什么不对其进行基准测试,看看它的功能?共享内存比注册文件慢,因此可能会影响性能,但影响程度可能取决于代码和硬件。上几天不得不重新安装计算机,因此没有安装CUDA。也许有人已经有了结果。@djmj你试过这个实验吗?还没有,没有时间,我必须在接下来的3周内做一些CUDA来学习,但我没有最新的卡片来进行合理的测试(只有一张1.1的卡片)。最有趣的测试用例是当需要一个寄存器存储在本地内存中时,我真的认为这样一个简单的计算可以在每个线程中进行。但只有一个实验能证明这一点。广播不会引起银行冲突。
__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();
}