这是一个关于如何确定CUDA网格、块和线程大小的问题。这是对已发布问题的附加问题here https://stackoverflow.com/a/5643838/1292251.
通过此链接,talonmies 的答案包含一个代码片段(见下文)。我不明白“通常通过调整和硬件限制选择值”的评论。
我在 CUDA 文档中没有找到很好的解释或说明来解释这一点。总而言之,我的问题是如何确定最佳的blocksize
(线程数)给出以下代码:
const int n = 128 * 1024;
int blocksize = 512; // value usually chosen by tuning and hardware constraints
int nblocks = n / nthreads; // value determine by block size and total work
madd<<<nblocks,blocksize>>>mAdd(A,B,C,n);
该答案有两个部分(我写的)。一部分很容易量化,另一部分则更具经验性。
硬件限制:
这是容易量化的部分。当前 CUDA 编程指南的附录 F 列出了许多硬限制,这些限制限制了内核启动时每个块可以拥有的线程数。如果超过其中任何一个,您的内核将永远不会运行。它们可以大致概括为:
- 每个块总共不能有超过 512/1024 个线程(计算能力 http://www.geeks3d.com/20100606/gpu-computing-nvidia-cuda-compute-capability-comparative-table/分别为 1.x 或 2.x 及更高版本)
- 每个块的最大尺寸限制为
[512,512,64]/[1024,1024,64](计算1.x/2.x或更高版本)
- 每个块消耗的寄存器总数不能超过 8k/16k/32k/64k/32k/64k/32k/64k/32k/64k
(计算1.0,1.1/1.2,1.3/2.x-/3.0/3.2/3.5-5.2/5.3/6-6.1/6.2/7.0)
- 每个块不能消耗超过 16kb/48kb/96kb 的共享内存(计算
1.x/2.x-6.2/7.0)
如果您保持在这些限制范围内,您可以成功编译的任何内核都将启动而不会出现错误。
性能调整:
这是经验部分。您在上述硬件限制内选择的每个块的线程数可以并且确实会影响在硬件上运行的代码的性能。每个代码的行为方式都会有所不同,量化它的唯一真正方法是通过仔细的基准测试和分析。但同样,非常粗略地总结一下:
- 每个块的线程数应该是 warp 大小的整数倍,在所有当前硬件上为 32。
- GPU 上的每个流式多处理器单元必须具有足够的活动扭曲,以充分隐藏架构的所有不同内存和指令管道延迟并实现最大吞吐量。这里的正统方法是尝试实现最佳硬件占用率(什么罗杰·达尔的回答 https://stackoverflow.com/a/9986071/681865指的是)。
第二点是一个巨大的主题,我怀疑是否有人会尝试在一个 StackOverflow 答案中涵盖它。有人围绕问题各方面的定量分析撰写博士论文(参见这个演示文稿 http://www.nvidia.com/content/gtc-2010/pdfs/2238_gtc2010.pdf作者:瓦西里·沃尔科夫(Vasily Volkov),来自加州大学伯克利分校这张纸 http://www.stuffedcow.net/research/cudabmk作者是多伦多大学的亨利·黄(Henry Wong),举例说明了这个问题到底有多复杂)。
在入门级别,您应该主要意识到您选择的块大小(在上述约束定义的合法块大小范围内)可以并且确实会对代码的运行速度产生影响,但这取决于硬件您拥有以及您正在运行的代码。通过基准测试,您可能会发现大多数重要代码在每块 128-512 个线程范围内都有一个“最佳点”,但您需要进行一些分析才能找到最佳点。好消息是,由于您正在处理扭曲大小的倍数,因此搜索空间非常有限,并且相对容易找到给定代码段的最佳配置。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)