想象一下,我已经开发了CUDA内核并调整了块大小和网格大小,以在我的机器上获得最佳性能。但是,如果我将应用程序提供给具有不同GPU的客户,则他可能需要其他设置来实现网格大小和块大小,以获得最佳性能。 如何在运行时更改网格大小和块大小,以使内核在不同的GPU上运行最佳?
答案 0 :(得分:2)
更改网格大小时,将更改线程总数。然后,将重点放在总线程上,主要目标是您正在运行的GPU的最大运行中线程承载能力。
试图最大程度地利用其运行的GPU的GPU代码,应该尝试至少拥有那么多线程。越少越好,越不可能有很大的改变。
此目标易于计算。对于大多数GPU,它是GPU中SM数量的2048倍。 (Turing GPUs have reduced the maximum thread load per SM from 2048 to 1024)。
您可以通过调用cudaGetDeviceProperties()
(研究deviceQuery
示例代码)来在运行时找出GPU中SM的数量。
一旦您知道SM的数量,就将其乘以2048。这就是要在网格中启动的线程数。在这种调整/近似水平上,无需更改每个块的调整线程数。
确实,您的特定代码可能无法在每个SM上实际实现2048个线程(这与占用率的讨论有关)。但是,对于一个简单的目标,这不会有任何伤害。如果您已经知道代码的实际占用能力,或者已经使用occupancy API来确定代码的使用能力,则可以将目标从每个SM 2048个线程缩减到更低的数量。但是这种缩减可能根本无法提高代码的性能。