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