Tak*_*ads 5 shader hlsl unity-game-engine compute-shader
假设我想使用计算着色器来运行 Kernel_X,线程尺寸为 (8, 1, 1)。
我可以将其设置为:
在脚本中:
Shader.Dispatch(Kernel_X, 8, 1, 1);
Run Code Online (Sandbox Code Playgroud)
在着色器中:
[numthreads(1,1,1)]
void Kernel_X(uint id : SV_DispatchThreadID) { ... }
Run Code Online (Sandbox Code Playgroud)
或者我可以这样设置:
在脚本中:
Shader.Dispatch(Kernel_X, 1, 1, 1);
Run Code Online (Sandbox Code Playgroud)
在着色器中:
[numthreads(8,1,1)]
void Kernel_X(uint id : SV_DispatchThreadID) { ... }
Run Code Online (Sandbox Code Playgroud)
据我所知,在这段代码的末尾,维度将是 (8, 1, 1); 然而,我想知道交换数字实际上有何不同。我的猜测是,运行 Dispatch (Kernel_X, 8, 1, 1) 会“运行”1x1x1 内核 8 次,而运行 numthreads(8,1,1) 将运行 8x1x1 内核一次。
Biz*_*rus 12
要理解其中的差异,需要一些硬件知识:
在内部,GPU 在所谓的波前上工作,这是 SIMD 样式的处理单元(就像一组线程,每个线程可以拥有自己的数据,但它们都必须在完全相同的时间执行完全相同的指令) ,总是)。每个波前的线程数取决于硬件,但通常为 32 (NVidia) 或 64 (AMD)。
现在,[numthreads(8,1,1)]您请求着色器线程组大小为 8 x 1 x 1 = 8 个线程,硬件可以在其波前之间自由分配。因此,每个波前有 32 个线程,硬件将为每个着色器组安排一个波前,该波前有 8 个活动线程(其他 24 个线程处于“非活动”状态,这意味着它们执行相同的工作,但会丢弃任何内存)写道)。然后,使用Dispatch(1, 1, 1),您将调度一个这样的着色器组,这意味着硬件上将运行一个波前。
您是否可以[numthreads(1,1,1)]改为使用,波前中只有一个线程可以处于活动状态。因此,通过调用Dispatch(8, 1, 1)该着色器组,硬件将需要运行 8 个着色器组(= 8 个波前),每个着色器组仅运行 1/32 个活动线程,因此虽然您会得到相同的结果,但您会浪费更多计算能力。
因此,一般来说,为了获得最佳性能,您希望着色器组大小为 32(或 64)的倍数,同时尝试使用尽可能合理的低数字调用 Dispatch。
| 归档时间: |
|
| 查看次数: |
10324 次 |
| 最近记录: |