【问题标题】:help me understand cuda帮我理解cuda
【发布时间】:2011-01-13 12:16:20
【问题描述】:

我在使用 cuda 理解 NVIDIA gpu 架构中的线程时遇到了一些麻烦。

请任何人澄清这些信息: 一个 8800 gpu 有 16 个 SM,每个 8 个 SP。所以我们有 128 个 SP。

我正在观看 stanford 的视频演示,它说每个 SP 都能够同时运行 96 个线程。这是否意味着它(SP)可以同时运行 96/32=3 个 warp?

此外,由于每个 SP 可以运行 96 个线程,并且每个 SM 中有 8 个 SP。这是否意味着每个 SM 可以同时运行 96*8=768 个线程??但是如果每个 SM 一次只能运行一个 Block,并且一个 Block 中的最大线程数是 512,那么并发运行 768 个线程并且最大 512 个线程的目的是什么?

一个更普遍的问题是:块、线程和经线是如何分配给 SM 和 SP 的?我读到每个 SM 一次执行一个块,一个块中的线程被划分为 warp(32 个线程),SP 执行 warp。

【问题讨论】:

  • 希望我已经在回答中进行了解释,但重要的一点是每个 SM 在任何给定时间都可以执行多个块。另外,数字 96 是一个红鲱鱼,不必担心每个 SP 的线程,只需担心每个 SM 的线程,让硬件处理更精细的细节。

标签: cuda gpu parallel-processing


【解决方案1】:

您应该查看 NVIDIA 网站上的 webinars,您可以加入实时会话或查看预先录制的会话。下面是一个快速概述,但我强烈建议您观看网络研讨会,因为您可以查看图表并同时对其进行解释,它们会很有帮助。

当您在 GPU 上执行一个函数(内核)时,它会作为 threadsblocksgrid 执行。

  • 线程是最细粒度的,每个线程在块内都有一个唯一标识符(threadIdx),用于选择要操作的数据。线程可以有相对大量的寄存器,也有一个称为 local memory 的私有内存区域,用于寄存器文件溢出和任何大型自动变量。
  • block 是一组在批处理中一起执行的线程。这种粒度级别的主要原因是块内的线程可以通过使用快速共享内存进行通信来进行协作。每个块都有一个唯一标识符 (blockIdx),它与 ​​threadIdx 一起用于选择数据。
  • grid 是一组共同执行 GPU 操作的块。

这就是逻辑层次结构。您实际上只需要了解在 GPU 上实现功能的逻辑层次结构,但是要获得性能,您还需要了解硬件,即 SM 和 SP。

一个GPU由SM组成,每个SM包含若干个SP。目前每个 SM 有 8 个 SP,每个 GPU 有 1 到 30 个 SM,但实际上,在您真正进步之前,实际数量并不是主要问题。

性能要考虑的第一点是warp。经线是一组 32 个线程(例如,如果您在一个块中有 128 个线程,那么线程 0-31 将在一个经线中,32-63 在下一个经线中,依此类推。由于几个原因,经线非常重要,最重要的是:

  • warp 中的线程绑定在一起,如果 warp 中的一个线程沿着 if-else 块的“if”一侧向下,而其他线程沿着“else”向下,那么实际上所有 32 个线程都将向下两侧.功能上没有问题,那些不应该采取分支的线程被禁用,所以你总是会得到正确的结果,但如果双方都很长,那么性能损失很重要。
  • warp 中的线程(实际上是半warp,但如果你把它用于warp,那么你在下一代也很安全)一起从内存中获取数据,所以如果你能确保所有线程都获取数据在同一个“段”内,您只需支付一次内存交易,如果它们都从随机地址获取,那么您将支付 32 次内存交易。有关详细信息,请参阅 Advanced CUDA C 演示文稿,但前提是您已准备好!
  • warp 中的线程(在当前 GPU 上也是半warp)一起访问共享内存,如果您不小心,您将遇到“银行冲突”,其中线程必须在彼此后面排队才能访问内存。

所以了解了扭曲是什么之后,最后一点是如何将块和网格映射到 GPU 上。

每个区块将从一个 SM 开始,并一直保留在那里直到完成。一旦完成,它将退出,并且可以在 SM 上启动另一个块。正是这种动态调度为 GPU 提供了可扩展性——如果你有一个 SM,那么所有块都在一个大队列上的同一个 SM 上运行,如果你有 30 个 SM,那么这些块将在 SM 之间动态调度。因此,您应该确保在启动 GPU 函数时,您的网格由大量块(至少数百个)组成,以确保它可以跨任何 GPU 扩展。

最后一点是,一个 SM 可以在任何给定时间执行多个块。这就解释了为什么一个 SM 可以处理 768 个线程(在某些 GPU 中甚至更多),而一个块最多只能处理 512 个线程(目前)。本质上,如果 SM 有可用的资源(寄存器和共享内存),那么它将占用额外的块(最多 8 个)。占用计算器电子表格(包含在 SDK 中)将帮助您确定在任何时候可以执行多少块。

很抱歉脑残,观看网络研讨会 - 会更容易!

【讨论】:

  • @Tom:自 2010 年以来发生了一些变化,请您更新答案中的各种数字(特别是最后一段)。这对我们真的很有帮助。
  • Advanced CUDA C 链接不再指向任何内容。请更新链接。
【解决方案2】:

一开始有点令人困惑,但知道每个 SP 执行类似于 4 路 SMT 的操作会有所帮助 - 它循环通过 4 个线程,每个时钟发出一条指令,每条指令有 4 个周期的延迟。这就是如何在 8 个 SP 上运行每个 warp 的 32 个线程。

与其用经纱、块、线程等来处理所有其他的东西,我会把你推荐给nVidia CUDA Forums,这种问题经常出现,并且已经有一些很好的解释。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-21
    • 1970-01-01
    • 2020-06-30
    • 1970-01-01
    • 2020-10-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多