12

我想知道我可以在 GPU 上调度的线程/线程组的“网格”。我正在使用 Direct Compute,所以我将给出一个使用该 API 的具体示例。例如,如果我调用 Dispatch(2,2,2),我理解它总共分派了 2x2x2 = 8 个线程组。但是,如果我调用 Dispatch(8,1,1),它也调度 8x1x1 = 8 个线程组,有什么区别?有性能差异吗?

PS与GPU上的线程相同的问题。在计算 (.hlsl) 文件中声明的 numthreads(2,2,2) 和 numthreads(8,1,1) 有什么区别?

任何帮助,将不胜感激。

4

2 回答 2

14

从纯粹的性能角度来看,实际上并没有区别,因为定义线程组或块的网格维度的能力更多是为了正确地将工作负载应用于问题本身的抽象,而不是为了性能. 换句话说,如果您的问题很好地抽象为 3D 体积网格,那么虽然可以使用将 3D 问题转换为 1D 线性表示的映射来创建相同数量的线程组/块,但该映射的抽象处理起来可能有点麻烦。此外,如果映射过于复杂,可能会对性能造成很小的影响。

您创建的线程组/块的数量以及这些块中的线程数很重要。在 Nvidia GPU 的情况下,每个线程组都分配给 GPU 上的 SMX 处理器,并且需要将多个线程块及其关联线程映射到 SMX,以隐藏由于内存访问等导致的延迟。此外,您希望在线程组/块中有足够的线程,以便您利用 GPU 的 SIMT(相同指令/多线程)功能。这意味着对于 Nvidia GPU 的 SMX 内的每个时钟周期(或一组时钟周期),它可以在锁步中同时执行 X 个线程。这个数字称为“线经”尺寸。你希望块中有足够的线程来填充这个扭曲计数,否则 GPU 的资源' 当块在 GPU 的各个 SMX 处理器上运行时,核心流处理器不会被用完。这个数字是 Nvidia Fermi GPU 上的 32 个线程。在 CUDA 中,您可以根据您正在使用的 GPU 查询此信息,尽管我假设使用 DirectCompute 这将被抽象掉。ATI 卡的流处理器也有一个“线程宽度”,即每个“波前”有 64 个线程。

理想情况下,最后你希望你的块中有足够的线程来填充 GPU 的波前或扭曲大小中的线程数,然后有很多块可以映射到 GPU 上的每个流处理器,这样它们每当遇到高延迟操作时,都可以在流处理器上保持运行并换出。这最大限度地提高了 GPU 的计算带宽。

于 2012-09-22T00:40:27.693 回答
2

块可以以 3 维方式排列线程。

让我们举个例子。假设您要调度 32 个线程。这 32 条线可以以 3 维方式排列。想象一下具有 X、Y 和 Z 轴的轴系统。您可以仅将所有 32 个线程与 X 轴一起排列。即 (32,1,1)。或者您可以将它与 X 和 Y 轴一起排列(如 2D 矩阵)(8,4,1),即 8 列,4 行。或者您也可以以 3 维方式排列,(8,2,2) 即 8 列,2 行,宽度为 2(想象一个高度为 8,宽度为 2,长度为 2 的立方体).. 尝试想象并构建图片你的想法。

于 2012-10-18T09:34:01.610 回答