【问题标题】:CUDA model - what is warp size?CUDA 模型 - 什么是经纱尺寸?
【发布时间】:2011-04-06 02:50:51
【问题描述】:

最大工作组大小和warp 大小之间有什么关系?假设我的设备有 240 个 CUDA 流处理器 (SP) 并返回以下信息 -

CL_DEVICE_MAX_COMPUTE_UNITS:30

CL_DEVICE_MAX_WORK_ITEM_SIZES:512 / 512 / 64

CL_DEVICE_MAX_WORK_GROUP_SIZE:512

CL_NV_DEVICE_WARP_SIZE:32

这意味着它的每个流式多处理器(即计算单元)有 8 个 SP。那么warp size = 32 与这些数字有什么关系呢?

【问题讨论】:

    标签: cuda gpgpu


    【解决方案1】:

    直接回答:warp 大小是 warp 中的线程数,它是硬件实现中用于合并内存访问和指令调度的细分。

    推荐阅读:

    正如@Matias 提到的,我会去阅读CUDA C Best Practices Guide(您必须滚动到它列出的底部)。查看第 164 页附录 G.1 中的表格可能会对您有所帮助。

    说明:

    CUDA 是在两个级别上提供并行性的语言。你有线程,你有线程块。这在执行内核时最为明显;您需要指定每个线程块的大小以及在内核参数之前的 >> 之间的线程块数。

    CUDA 没有告诉您的是,事情实际上发生在四个级别,而不是两个级别。在后台,您的线程块实际上分为称为“warp”的子块。这里有一个简短的比喻来帮助解释真正发生的事情:

    简要比喻:

    假设您是一位对高中生当前的数学能力感兴趣的教育家/研究人员/政治家。您的计划是对 10,240 名学生进行测试,但您不能将他们全部放在足球场或其他地方进行测试。细分(并行化)您的数据收集是最容易的——因此您去 20 所不同的高中,要求他们的 512 名高年级学生分别参加数学考试。

    高中的数量,20,类似于“块”的数量/“线程块的数量”。老年人的数量,512,类似于每个块中的线程数,也就是“每个块的线程数”。

    您收集您的数据,这就是您所关心的。您不知道(也没有真正在意)每所学校实际上都细分为教室。因此,您的 512 名高年级学生实际上被分为 16 组,每组 32 人。此外,这些学校都没有真正拥有所需的资源——每个教室只有 16 个计算器。因此,在任何时候,每个教室只有一半的人可以参加您的数学考试。

    高级数 512 表示启动 CUDA 内核时请求的每个块的线程数。实现硬件可能会进一步将其划分为 16 个连续的 32 个线程块,以处理请求的线程的全部数量,即 512。数字 32 是 warp 大小,但这可能会因不同的硬件世代而异。 p>

    我可以继续延伸一些愚蠢的规则,比如任何一所学校只有 8 个教室可以同时参加考试,因为他们只有 8 位老师。你不能同时抽样超过 30 所学校,因为你只有 30 名监考人员......

    回到你的问题:

    使用比喻,您的程序希望尽可能快地计算结果(您希望收集数学测试)。你发布一个带有一定数量块(学校)的内核,每个块都有一定数量的线程(学生)。您一次只能运行这么多块(收集您的调查回复需要每所学校一名监考人员)。在 CUDA 中,线程块在流式多处理器 (SM) 上运行。变量:CL_DEVICE_MAX_COMPUTE_UNITS 告诉您一张特定卡有多少 SM,30。这因硬件而异——查看CUDA C Best Practices Guide 的附录 A 中的表格。请注意,无论计算能力如何(1.X 或 2.X),每个 SM 只能同时运行八个块。

    线程块的最大尺寸为:CL_DEVICE_MAX_WORK_ITEM_SIZES。考虑将线程布置在网格中;线程数不能超过 512 个。列的线程数不能超过 512 个。并且您不能堆叠超过 64 个线程高。接下来,有一个最大值:CL_DEVICE_MAX_WORK_GROUP_SIZE 线程数,512,可以组合在一个块中。所以你的线程块的尺寸可能是:

    512 x 1 x 1

    1 x 512 x 1

    4 x 2 x 64

    64 x 8 x 1

    等等……

    请注意,从 Compute Capability 2.X 开始,您的块最多可以有 1024 个线程。最后,变量CL_NV_DEVICE_WARP_SIZE 指定扭曲大小,32(每个教室的学生人数)。在 Compute Capability 1.X 设备中,内存传输和指令调度发生在 Half-Warp 粒度(每个教室只有 16 个计算器)。在 Compute Capability 2.0 中,内存传输按 Warp 分组,因此同时进行 32 次 fetch,但指令调度仍然仅按 Half-Warp 分组。对于 Compute Capability 2.1,内存传输指令分派均由 Warp 进行,32 个线程。 这些东西可以而且将会在未来的硬件中改变。

    所以,我的话!让我们进入正题:

    总结:

    我已经描述了经纱/线程布局和其他类似内容的细微差别,但这里有几点需要牢记。首先,您的内存访问应该以 16 或 32 为一组“可分组”。因此,请保持块的 X 维度为 32 的倍数。其次,也是最重要的,以充分利用特定 gpu ,您需要最大化入住率。没有 5 块 512 线程。并且没有 1,000 个 10 个线程的块。我会强烈建议查看Excel-based spreadsheet(也可以在OpenOffice 中使用??我想??)它会告诉您特定内核调用的GPU占用率(线程布局和共享内存要求)。我希望这个解释会有所帮助!

    【讨论】:

    • 非常好的答案和比喻。只是想补充一点,AMD 有类似的概念,称为 Wavefront,目前是 64 个线程/wavefront。
    • 嗯。我不知道。我没有花太多时间研究 AMD 产品。您是否知道这是否会随着 Fusion 产品而发生巨大变化?
    • 未来的 fusion 部分都是基于 Evergreen 架构,所以波前应该保持 64 线程:highperformancegraphics.org/media/Hot3D/HPG2010_Hot3D_AMD.pdf
    • @M.Tibbits 你能说出你指的是哪个excel表吗?
    【解决方案2】:

    warp 大小是多处理器同时执行的线程数。 NVIDIA 多处理器可以使用硬件多线程同时从同一块执行多个线程。

    考虑 warp 大小很重要,因为所有内存访问都合并为 warp 大小的倍数(32 字节、64 字节、128 字节),这样可以提高性能。

    CUDA C Best Practices Guide 包含有关此类优化的所有技术信息。

    【讨论】:

      【解决方案3】:

      直接回答很简单:在Nvidia中,由THREAD组成的BLOCK由程序员设置,WARP为32(由32个线程组成),是计算单元同时执行的最小单元。 在 AMD 中,WARP 称为 WAVEFRONT(“波”)。

      在 OpenCL 中,WORKGROUPs 表示 CUDA 中的 BLOCK,而 WORKITEMs 表示 CUDA 中的 THREAD。

      【讨论】:

      • 这在某种程度上是一个信息丰富的答案;但是,它并没有真正告诉我们有关扭曲以及在编写代码时如何将它们考虑在内的信息。正如理查德·费曼 (Richard Feynmann) 曾经说过的那样:“知道某事物的名称并不意味着你就理解它。”为了教好,你应该解释一些东西是如何运作或使用的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-18
      • 2021-09-28
      • 2011-07-03
      • 2022-01-16
      • 1970-01-01
      • 2018-07-08
      相关资源
      最近更新 更多