Metal计算着色器线程组和线程执行宽度

3

能否以简单的方式解释Metal计算着色器中的线程组概念以及其他术语,例如SIMD组、threadExecutionWidth(波前)?我已经阅读了文档,但仍感到困惑。例如,如果我有一个1024x1024的图像,我可以有多少个线程组,如何将线程映射到每个像素,可以同时运行多少个线程等等?我找不到描述计算着色器和这些概念的WWDC视频。

1个回答

7

线程组是一组协同工作以解决某个(子)问题的线程。您可以在线程组中拥有最多5121024个线程(取决于您使用的设备)。

threadExecutionWidth是所使用的SIMD组的大小。它通常为32,这意味着每个SIMD组中有32个线程。为了实现最佳性能,您的线程组中的线程数应该是threadExecutionWidth的倍数。(这确实就是其他人所称的wavefront或warp)。

如果您有一个1024x1024像素的图像,并且您希望一个线程处理一个像素,而最大线程组大小为512,那么您可以创建一个由32x64大小为32x16(即512)的线程组组成的1024x1024线程网格。

但实际上,您可以按任何方式划分线程。您也可以拥有一个由2x1024大小为512x1的线程组组成的网格,或其他任何方式。


你没有解释SIMD组的重要性。有任何WWDC视频涵盖这些主题吗?另外,如果maxTotalThreadsPerThreadGroup为512,并且图像为1024x1024,我们可以安全地假设像素将以512个一组串行处理吗?换句话说,下一组512个像素将不会被处理,除非前面的512个像素已经被处理了? - Deepak Sharma
另外,我们如何定义网格的形状——1x512、2x256或32x16等?我无法找到任何详细的教程或WWDC视频描述这些细节,除非有人能指出来。 - Deepak Sharma
4
GPU硬件被分成几个SIMD组。如果threadExecutionWidth为32,maxThreadsPerThreadgroup为512,则意味着硬件中有512/32=16个这些SIMD组,每个SIMD组可以同时运行32个线程。GPU将决定在哪个SIMD组中安排32个线程的组-作为开发人员,您无法控制此过程。由于Apple未公开实际硬件细节,因此GPU的工作方式大多是猜测。 - Matthijs Hollemans
2
关于“我们可以安全地假设像素将按512个串行处理吗?”首先,作为开发人员确定此线程网格的外观以及每个线程应执行的操作。GPU并不在意,它只会启动您请求的线程。其次,GPU可以以任何顺序启动这些线程,但它总是以threadExecutionWidth的线程组为单位进行启动,因为它必须始终一次运行整个SIMD组。即使您只使用1个线程,它仍然会运行整个SIMD组,并且只是丢弃其他31个线程的结果。 - Matthijs Hollemans
深入Metal-Feature-Set-Tables.pdf(页码9上的脚注3)中,他们说512或1024是"理论最大值",并且建议你在运行时获取MTLComputePipelineState.maxTotalThreadsPerThreadgroup来了解实际最大值。 - whlteXbread

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接