我正在尝试使用 CUDA 2.0 (NVIDIA 590) 处理大型结构数组。我想为此使用共享内存。我已经尝试使用 CUDA 占用计算器,尝试为每个线程分配最大共享内存,以便每个线程可以处理数组的整个元素。然而,我在计算器中看到的(每块共享内存)/(每块线程)的最大值为 32 字节,100% 多处理器负载是 32 字节,这对于单个元素(数量级)来说是不够的。32 字节是(每块共享内存)/(每块线程)的最大可能值吗?是否可以说哪个alternative4native更可取-在全局内存中分配部分数组还是仅使用负载不足的多处理器?还是只能通过实验来决定?我可以看到的另一种选择是多次处理数组,但它看起来像是最后的手段。
1 回答
在设计 CUDA 内核时,您需要牢记许多硬件限制。以下是您需要考虑的一些限制条件:
- 您可以在单个块中运行的最大线程数
- 一次可以在流式多处理器上加载的最大块数
- 每个流式多处理器的最大寄存器数
- 每个流式多处理器的最大共享内存量
您首先达到的这些限制中的哪一个都会成为限制您的占用率的约束(您所说的“100% 多处理器负载”是指最大占用率吗?)。一旦达到一定的入住率阈值,关注入住率就变得不那么重要了。例如,33%的占用并不意味着你只能达到GPU最大理论性能的33%。Vasily Volkov 在 2010 GPU 技术大会上做了一场精彩的演讲,建议不要过分担心占用,而是尝试通过在内核中使用一些显式缓存技巧(和其他东西)来尽量减少内存事务。你可以在这里观看演讲:http://www.gputechconf.com/gtcnew/on-demand-GTC.php?sessionTopic=25&searchByKeyword=occupancy&submit=&select=+&sessionEvent=&sessionYear=&sessionFormat=#193
确保您使用的内核设计能够提供最佳性能的唯一真正方法是测试所有可能性。而且您需要对运行它的每种类型的设备重新进行此性能测试,因为它们在某种程度上都有不同的约束。这显然很乏味,尤其是当不同的设计模式导致根本不同的内核时。我通过使用模板引擎在运行时根据设备硬件规范动态生成内核,在某种程度上解决了这个问题,但这仍然有点麻烦。