关于kernel线程配置

kernel的线程配置怎么才能达到最高的运行速度, 这个问题一直比较纠结.

此前一直是用扫描的方法确定, 就是对一个kernel函数用所有可能的线程配置进行运行,选择其中运行最快的配置使用.

在做二维问题的时候,这种扫描方法还可以,扫描(grid.x, grid.y, block.x, block.y)的组合, 一般扫描几万个组合就可以了, 每一次调用kernel的时间很短,总共的扫描时间也就不算长.

但是,做三维问题的时候,悲剧了:
①线程结构是三维的, 要扫描(grid.x, grid.y, block.x, block.y, block.z)的组合, 这就多了去了
②每次调用kernel的时间是二维问题的kernel的几十倍到几百倍
这样, 扫描配置的时间十分之巨~要么慢慢慢慢慢等, 要么把扫描的数目减少一些(但是这样有怕把最佳配置给漏掉了), 很纠结

请问各位, 我这种扫描方法是不是很土鳖?
大家都是怎么搞这个问题的?
配置都是依据什么原则选定的?
交流一下 :slight_smile:

这种扫描方法很常用,也很实用。但是没有必要扫那么多,因为block尺寸最好是32或64的倍数(这不是必须),我的意思是说,你可以依据你的应用的特点来决定要测试那些配置,我相信在你扫描所有的可能性时,会发现有些组合明显不是最优的。

LZ您好,kernel的线程配置自身并不影响运行速度。

kernel的运行速度或者说执行效率(给定硬件下的速度),常见的影响因素有,访存合并与否、block规模、总的线程规模、是否有因素影响occupancy、访存和计算的比例如何、计算的指令吞吐量如何、warp内分支情况如何、是否有计算和传输互相掩盖延迟等。

不同的线程配置,可能在利用线程编号寻址的时候,会有不同的计算量,但这个差别很小,kernel有些规模的话,这个影响应该不大。

如果是不同线程配置,影响了其他因素,比如说影响了合并访问什么的,那么需要具体分析,而且这并不是因为线程配置而直接影响的。

综上,建议您根据算法实现方便和需要,设置线程配置,并满足基本的要求,如合并访问、block大小、线程整体规模等,一般来说就可以得到较好的效果,在此基础上,可以根据NVVP的测试结果,寻找瓶颈,加以优化。

欢迎您回归CUDAZONE,祝您编码愉快~

多谢风大~
之前看参考也是说block尺寸最好是束的倍数
不过用起来也不尽然
譬如我做的二维的线程结构, 用上面说的扫描方法,对于(grid.x, grid.y, block.x, block.y)中的每个参数都在2~16之间扫描, 最后得到的最快的配置是(11-2-5-15) (对于某个kernel)! 还有奇数:L,
本来还想只扫描偶数的, 这样看来就不合适了(如果扫描地没问题的话)
:frowning:

thanks~~
NVVP?没用过哈:L

等等, 32貌似是很神奇
看了看其他的几个测试, 速度比较快的配置的block都是2X16的
继续搞搞看…

NVVP就是那个自带的visual profiler,您不妨一试?

祝您好运!

32是warp的宽度,你也可以看作是SIMT的宽度或者看做是执行时SIMD的宽度,所以这是一个特殊的数字。

因为是single instruction,所以它们的行为最好是一致的。如果不一致,会造成多次执行并丢弃无效结果等开销。

欢迎您继续测试~

visual profiler听说过, 还么用过…