Configuration 如何适当调整CUDA网格的大小并启动它?
第一个问题: 假设我需要在具有1.3计算能力的特斯拉C1060上启动一个包含229080个线程的内核 因此,根据文档,这台机器有240个内核,每个对称多处理器上有8个内核,总共有30个SMs 对于“并发”运行的30720个线程,每个SM最多可以使用1024个线程 现在,如果我定义256个线程的块,这意味着每个SM可以有4个块,因为1024/256=4。因此,这些30720个线程可以在所有SMs的120个块中排列 现在以229080线程为例,我需要229080/256=~895(四舍五入)块来处理所有线程 现在让我们假设我想调用一个内核,我必须使用那些229080线程,所以我有两个选择。第一个是将问题分解,以便在一个for循环中调用内核~8次,每次调用120个块和30720个线程(229080/30720)。这样我就可以确保设备完全被占用。另一个选项是使用895个块的网格为整个229080线程调用内核,在这种情况下,许多块将保持空闲,直到SM使用它拥有的8个块完成 那么,哪一个是首选方案?那些街区闲置等待有什么区别吗?他们需要资源吗 第二个问题 假设在我调用的内核中,我需要访问非合并的全局内存,因此可以选择使用共享内存 然后我可以使用每个线程从全局内存上的数组中提取一个值,比如说Configuration 如何适当调整CUDA网格的大小并启动它?,configuration,cuda,shared-memory,Configuration,Cuda,Shared Memory,第一个问题: 假设我需要在具有1.3计算能力的特斯拉C1060上启动一个包含229080个线程的内核 因此,根据文档,这台机器有240个内核,每个对称多处理器上有8个内核,总共有30个SMs 对于“并发”运行的30720个线程,每个SM最多可以使用1024个线程 现在,如果我定义256个线程的块,这意味着每个SM可以有4个块,因为1024/256=4。因此,这些30720个线程可以在所有SMs的120个块中排列 现在以229080线程为例,我需要229080/256=~895(四舍五入)块来处理
global\u array
,它的长度是229080。现在,正如我正确理解的那样,在复制到共享内存时必须避免分支,因为块上的所有线程都需要到达syncthreads()
调用,以确保它们都可以访问共享内存
这里的问题是,对于229080线程,我需要的正是229080/256=894.84375块,因为有216个线程的剩余。我可以将这个数字四舍五入,得到895个块,最后一个块将只使用216个线程
但是由于我需要从global_array
中提取共享内存的值,该值的长度为229080,并且我不能使用条件语句来防止最后40个线程(256-216)访问global_array
上的非法地址,那么在处理共享内存加载时,我如何避免这个问题呢
那么,哪一个是首选方案?那些街区闲置等待有什么区别吗?他们需要资源吗
根据您的描述,单个内核是首选的。排队但未分配给SM的ThreadBlock不会占用您需要担心的任何资源,而且机器的设计绝对可以处理类似的情况。在其他条件相同的情况下,8个内核调用的开销肯定会更慢
现在,正如我正确理解的那样,在复制到共享内存时必须避免分支,因为块上的所有线程都需要到达syncthreads()调用,以确保它们都可以访问共享内存
这种说法表面上是不正确的。您可以在复制到共享内存时进行分支。您只需确保:
\uuu syncthreads()
在分支构造之外,或者\uuuuxynchthreads()
(这实际上意味着对于块中的所有线程,至少在\uxynchthreads()
障碍所在的点上)int idx = threadIdx.x + (blockDim.x * blockIdx.x);
if (idx < data_size)
shared[threadIdx.x] = global[idx];
__syncthreads();
int-idx=threadIdx.x+(blockDim.x*blockIdx.x);
if(idx<数据大小)
共享的[threadIdx.x]=全局的[idx];
__同步线程();
这是完全合法的。块中的所有线程,无论它们是否参与到共享内存的数据复制,都将到达屏障
那么,哪一个是首选方案?那些街区闲置等待有什么区别吗?他们需要资源吗
根据您的描述,单个内核是首选的。排队但未分配给SM的ThreadBlock不会占用您需要担心的任何资源,而且机器的设计绝对可以处理类似的情况。在其他条件相同的情况下,8个内核调用的开销肯定会更慢
现在,正如我正确理解的那样,在复制到共享内存时必须避免分支,因为块上的所有线程都需要到达syncthreads()调用,以确保它们都可以访问共享内存
这种说法表面上是不正确的。您可以在复制到共享内存时进行分支。您只需确保:
\uuu syncthreads()
在分支构造之外,或者\uuuuxynchthreads()
(这实际上意味着对于块中的所有线程,至少在\uxynchthreads()
障碍所在的点上)