在一个库中,我使用了几个CUDA内核的调用。当然,我希望获得最佳性能。用户使用库的方式可能会有所不同。
块数/线程数对此有很大影响。
是否有一些规则可以选择块数/线程数以获得最佳性能?
例如(只是一个问题),选择高块、低线程是最好的吗?还是反过来呢?或者最好使用GetDeviceProperties()中的某些值?
在一个库中,我使用了几个CUDA内核的调用。当然,我希望获得最佳性能。用户使用库的方式可能会有所不同。
块数/线程数对此有很大影响。
是否有一些规则可以选择块数/线程数以获得最佳性能?
例如(只是一个问题),选择高块、低线程是最好的吗?还是反过来呢?或者最好使用GetDeviceProperties()中的某些值?
我认为这完全是经验问题。
块大小和网格大小取决于很多因素,如算法、每个线程的工作量、资源、延迟等。
通常情况下,我会先将其设置为256 * 256,并经常进行调整以选择更好的大小。
在Thrust中,他们会选择类似257的块大小以避免银行冲突。
有很多资源可以帮助您进行选择,例如: 延迟和块大小(http://www.lsr.nectec.or.th/images/e/e6/Cuda_Optimization2.pdf)
总之,试一试并更新它。
最好在一个块中至少有一个完整的线程束,否则你只能利用可用的处理能力很少。此外,通常希望在一个块中有一个可以被线程束大小整除的线程数。
在一个块中使用的总线程数取决于你的资源使用情况。原则上,你要争取实现大的占用率。限制因素是可用的共享内存和寄存器。如果你使用了大量的共享内存和/或寄存器,则最大可实现的占用率会下降。这时,对每个块的线程数进行分析和微调,直到找到一个甜点,使得实现和理论占用率的比值最大化,并且总占用率本身尽可能接近100%。
作为一个经验法则,你要在保持良好占用率的同时最大化每个块中的线程数。在分析步骤中,自动迭代可能的块/线程数组合以找到极值组合是完全有意义的。
你可以使用由NVIDIA提供的“依赖计算器.xls”来选择最佳配置[你需要尝试在xls中更改线程和块的值],从而实现最佳占用率,进而获得最佳性能。