最近,尝试gpu编程加速,经过权衡最终选择cuda。查阅资料 在 文献2 出处发现涉及到cuda最优线程数目设置,最优线程数目会影响执行效率。根据他/她提供的链接,仍然不明白为什么会有这个限制。后面刚好看《深入浅出谈cuda》,作者提到这个问题。我大致总结一下:1.受显卡 多处理器 的寄存器数目限制,GeForce 8800GT的显卡 最多8192寄存器,假设每个线程需要的寄存器等于16,则最多只有512个线程。再高的线程将会将数据切换的显卡显存,反而降低执行效率;
以下是摘录:
在执行 CUDA 程序的时候,每个 stream processor 就是对应一个 thread。 每个 multiprocessor
则对应一个 block。从之前的文章中,可以注意到一个 block 经常有很多个 thread(例如 256
个),远超过一个 multiprocessor 所有的 stream processor 数目。这又是怎么回事呢?
实际上,虽然一个 multiprocessor 只有八个 stream processor,但是由于 stream processor 进行
各种运算都有 latency,更不用提内存存取的 latency,因此 CUDA 在执行程序的时候,是以
warp 为单位。目前的 CUDA 装置,一个 warp 里面有 32 个 threads,分成两组 16 threads
的 half-warp。由于 stream processor 的运算至少有 4 cycles 的 latency,因此对一个 4D 的
stream processors 来说,一次至少执行 16 个 threads(即 half-warp)才能有效隐藏各种运算
的 latency。
由于 multiprocessor 中并没有太多别的内存,因此每个 thread 的状态都是直接保存在
multiprocessor 的寄存器中。所以,如果一个 multiprocessor 同时有愈多的 thread 要执行,就
会需要愈多的寄存器空间。例如,假设一个 block 里面有 256 个 threads,每个 thread 用到
20 个寄存器,那么总共就需要 256x20 = 5,120 个寄存器才能保存每个 thread 的状态。
目前 CUDA 装置中每个 multiprocessor 有 8,192 个寄存器,因此,如果每个 thread 使用到
16 个寄存器,那就表示一个 multiprocessor 同时最多只能维持 512 个 thread 的执行。如果
同时进行的 thread 数目超过这个数字,那么就会需要把一部份的数据储存在显卡内存中,就
会降低执行的效率了。
因此,对于最佳线程设置。查阅手上显卡多处理器寄存器数目,以及每个线程需要的寄存器数目,进行最优设置。
以上是,截止目前资料,尚未实践。欢迎对于最佳线程数目设置有建议的的人回复交流。
参考文献:
1.《深入浅出谈CUDA》
2.lingerlanlan 的****博客:用cuda实现图像缩放