CL_DEVICE_MAX_COMPUTE_UNITS: 30
CL_DEVICE_MAX_WORK_ITEM_SIZES: 512 / 512 / 64
CL_DEVICE_MAX_WORK_GROUP_SIZE: 512
CL_NV_DEVICE_WARP_SIZE: 32
这意味着每个流多处理器(即计算单元)有8个SP。现在,warp大小= 32与这些数字有什么关系?
直接回答:Warp大小是一个warp中的线程数,它是硬件实现中用于合并内存访问和指令分派的子细分。
建议阅读:
如@Matias所提到的,建议阅读CUDA C最佳实践指南(需要滚动到底部列出的部分)。你可能需要仔细观察第164页的附录G.1中的表格。
解释:
CUDA是一种语言,提供了两个级别的并行性。你有线程和线程块。当你执行一个Kernel时,你需要在<<< >>>之间指定每个线程块的大小以及线程块的数量。
然而,CUDA没有告诉你的是实际上有四个级别的并行性。在后台,你的线程块实际上被划分为称为“warp”的子块。这里有一个简短的比喻来帮助解释正在发生的事情:
简短的比喻:
假设你是一名对高中毕业生当前的数学能力感兴趣的教育工作者/研究人员/政治家。你的计划是给10,240名学生进行测试,但你不能只是把他们都放在一个足球场或其他地方,然后给他们测试。最简单的方法是对数据进行细分(并行化)--所以你去了20个不同的高中,要求他们每个有512名毕业生参加数学测试。
高中数量20相当于“块”的数量/”线程块的数量”。512名毕业生的数量类似于每个块内的线程数,也就是“每个块的线程数”。
你收集数据,这是你关心的全部内容。但你不知道(也并没有真正在意),每所学校实际上都被分成了教室。因此,你的512名高中毕业生实际上被分成了16组32人。而且,这些学校中没有一个真正拥有所需的资源,每个教室只有16台计算器。因此,在任何时候,每个教室只有一半的学生能参加你的数学测试。
512位高中毕业生的数量表示启动CUDA Kernel时请求的每个线程块的数量。实施硬件可以进一步将其分成16个连续的32个线程块,以处理请求的所有线程数,即512。数字32是warp大小,但这可能因不同的硬件版本而有所不同。
我可以继续发挥愚蠢的规则,比如任何一所学校最多只有八个教室可以同时参加考试,因为他们只有八名教师。你不能同时抽样超过30所学校,因为你只有30个监考员......
回到您的问题:
使用这个比喻,你的程序想要尽快计算出结果(你想收集数学测试)。你发出一个包含一定数量的块(学校)和每个块中一定数量的线程(学生)的内核。你一次只能运行这么多块(收集调查响应需要每所学校有一个监考员)。在CUDA中,线程块在流式多处理器(SM)上运行。变量:CL_DEVICE_MAX_COMPUTE_UNITS
告诉你一个特定的卡有多少个SM,30。这根据硬件而大不相同--请查看CUDA C最佳实践指南附录A中的表格。请注意,每个SM无论计算能力(1.X还是2.X),都只能同时运行八个块。
线程块具有最大维度:CL_DEVICE_MAX_WORK_ITEM_SIZES
。将线程排列成网格,每行不能超过512个线程。每列不能超过512个线程。并且不能将超过64个线程堆叠在一起。此外,线程块的最大数量为CL_DEVICE_MAX_WORK_GROUP_SIZE
,即512个可以分组在一个块中的线程。因此,线程块的尺寸可以是:
512 x 1 x 1
1 x 512 x 1
4 x 2 x 64
64 x 8 x 1
等等...
请注意,自计算能力2.X起,您的块最多可具有1024个线程。最后,变量CL_NV_DEVICE_WARP_SIZE
指定了warp大小,即32(每个教室的学生人数)。在计算能力为1.X的设备上,内存传输和指令调度发生在半warp粒度下(每个教室只有16台计算机)。在计算能力2.0中,内存传输被分组为warp,因此同时进行32个提取,但指令调度仍然只按半warp分组。对于计算能力2.1,内存传输和指令调度都以warp方式进行,即32个线程。这些内容在未来的硬件中可能会发生变化。
因此,言归正传:
总结:
我已经描述了warp/thread布局等细微差别,但是这里有一些需要记住的事情。首先,你的内存访问应该可以以16或32个为一组。因此,请将您块的X维设为32的倍数。其次,最重要的是要最大化占用率以获得特定GPU的最佳性能。不要有5个拥有512个线程的块。也不要有1,000个只有10个线程的块。我强烈建议查看基于Excel的电子表格(在OpenOffice中也可以使用)它会告诉您特定内核调用(线程布局和共享内存需求)的GPU占用率将是多少。希望这次解释有所帮助!
Warp大小是一个多处理器同时执行的线程数。NVIDIA多处理器可以同时使用硬件多线程执行同一块中的几个线程。
考虑Warp大小非常重要,因为所有内存访问都被合并成Warp大小的倍数(32字节、64字节、128字节),这会提高性能。
CUDA C最佳实践指南包含了所有关于这些优化的技术信息。