我已经使用CUDA几周了,但是对于块/线程/线程组的分配仍有一些疑问。
我从教学的角度研究这个架构(大学项目),所以达到最高性能不是我的关注点。
首先,我想了解一下我是否掌握了以下事实:
程序员编写一个内核,并将其执行组织为线程块网格。
每个块分配给一个流多处理器(SM)。一旦分配,它就不能迁移到另一个SM。
每个SM将自己的块拆分成线程束(目前具有最大大小为32的线程)。线程束中的所有线程都在SM的资源上同时执行。
线程的实际执行由SM中包含的CUDA核心执行。线程和核心之间没有特定的映射。
如果线程束包含20个线程,但当前只有16个核可用,则线程束将不会运行。
另一方面,如果块包含48个线程,则它将被拆分为2个线程束,并且只要有足够的内存可用,它们将并行执行。
如果线程在一个核上启动,然后因为内存访问或长时间的浮点操作而被阻塞,它的执行可能会在另一个核上恢复。
这些正确吗?
现在,我有一块GeForce 560 Ti显卡,根据规格说明,它配备了8个SM,每个SM包含48个CUDA核心(总共384个核心)。
我的目标是确保架构的每个核心都执行相同的指令。假设我的代码不需要更多的寄存器,超过每个SM中可用的寄存器数量,我想象了不同的方法:
我创建8个具有48个线程的块,以便每个SM都有1个要执行的块。在这种情况下,48个线程将在SM中并行执行(利用所有可用的48个核心)吗?
如果我启动64个块,每个块有6个线程,是否会产生任何区别?(假设它们将在SMs之间平均映射)
如果我在计划的工作中“淹没”GPU(例如创建1024个块,每个块有1024个线程),是否可以合理地假设所有核心在某个时刻都将被使用,并且将执行相同的计算(假设线程从未停顿)?
是否有任何方法使用分析器检查这些情况?
有没有关于这些内容的参考资料?我读过CUDA编程指南以及“大规模并行处理器编程”和“CUDA应用设计与开发”中专门讲解硬件架构的章节;但我无法得到精确的答案。