关于如何选择#blocks & blockSize 已经有很多讨论,但我仍然遗漏了一些东西。我的许多担忧都解决了这个问题:CUDA Blocks/Warps/Threads 如何映射到 CUDA Cores? (为了简化讨论,有足够的 perThread 和 perBlock 内存。内存限制在这里不是问题。)
kernelA<<<nBlocks, nThreads>>>(varA,constB, nThreadsTotal);
1)为了让 SM 尽可能忙碌,我应该设置nThreads
为warpSize
. 真的?
2) 一个 SM 一次只能执行一个内核。也就是说,该 SM 的所有 HWcore 都只执行 kernelA。(不是一些运行 kernelA 的 HWcore,而其他运行 kernelB。)因此,如果我只有一个线程要运行,我将“浪费”其他 HWcore。真的?
3)如果warp-scheduler发出以单位为单位的工作warpSize
,并且每个SM有32个HWcore,那么SM将被充分利用。当 SM 有 48 个 HWcore 时会发生什么?当调度程序以 32 个块的形式发布工作时,如何保持所有 48 个内核的充分利用?(如果上一段是真的,调度器以HWcore大小为单位下发工作不是更好吗?)
4)看起来warp-scheduler一次排队2个任务。因此,当当前执行的内核停止或阻塞时,第二个内核被换入。(不清楚,但我猜这里的队列深度超过 2 个内核。)这是正确的吗?
5) 如果我的硬件的上限为每块 512 个线程 (nThreadsMax),这并不意味着具有 512 个线程的内核将在一个块上运行得最快。(同样,内存不是问题。)如果我将 512 线程内核分布在许多块上,而不仅仅是一个块,我很有可能会获得更好的性能。该块在一个或多个 SM 上执行。真的?
5a)我认为越小越好,但是我做多小有关系nBlocks
吗?问题是,如何选择那个值nBlocks
是体面的?(不一定是最优的。)是否有一种数学方法来选择nBlocks
,或者只是试错法。