我知道Disptach(x, y, z(将定义实例化多少组线程,numthreads(n, m, p(给出每个组的大小。
将调度和线程数组合在一起,给出线程总数。我还了解调度参数用于将参数传递给每个线程。
问题:
1( I 组 J 线程和 I 线程上的 J 组之间有性能差异吗?这两个选项提供相同数量的线程。
2(假设我必须处理一个大小仅在运行时已知的二维矩阵,那么使用Dispatch(DimX,DimY,1(和numthreads(1,1,1(很方便,这样我就可以准确地在每个矩阵元素上,其位置由DTid.xy给出。由于 numthreads(( 参数是在编译时确定的,我如何获得处理维度不是线程组大小的倍数且在编译时未知的矩阵所需的确切线程数?
1(是的,存在(或可能(性能差异,具体取决于实际数字和使用的硬件!
GPU(通常(包含多个所谓的线程"波"。这些波形以类似 SIMD 的方式工作(波形中的所有线程都同时执行相同的操作(。每波的确切线程数因供应商而异,但通常是 32(我知道的所有 NVidia GPU(或 64(大多数 AMD GPU(。
一组线程可以分布到多个波次。但是,单个波只能执行同一组的线程。因此,如果每组的线程数不是硬件波数的倍数,则波中有一些线程处于"空闲"状态(它们实际上正在执行与其他线程相同的操作,但不允许写入内存(,因此您将"失去"使用更多线程数获得的性能。
2(您很可能会选择适合您的硬件的线程计数(64 是一个很好的默认值,因为它也是 32 的倍数(,并使用分支将矩阵之外的线程标记为"非活动"(您可以使用常量缓冲区将矩阵/数据的大小传递给着色器(。由于这些非活动线程根本不做任何事情,硬件可以简单地将它们屏蔽为"只读"(类似于每组线程数小于波形大小时的处理方式(,这是相当便宜的。如果波次中的所有线程都标记为非活动,则硬件甚至可以选择完全跳过此波次的工作,这将是最佳的。
您还可以使用填充来确保您的矩阵/数据是每组线程数的倍数,例如零或单位矩阵或其他任何东西。但是,是否可以做到这一点取决于应用程序,我认为在大多数情况下,分支会同样快 - 如果不是更快的话。