164

我已经使用CUDA几个星期了,但是我对blocks/warps/thread的分配有些怀疑。 我正在从教学的角度(大学项目)研究架构,因此达到最佳性能不是我关心的问题。

首先,我想了解我是否了解这些事实:

  1. 程序员编写内核,并在线程块网格中组织其执行。

  2. 每个块都分配给一个流式多处理器 (SM)。一旦分配它就不能迁移到另一个 SM。

  3. 每个 SM 将自己的块拆分为 Warps(当前最大大小为 32 个线程)。warp 中的所有线程在 SM 的资源上同时执行。

  4. 线程的实际执行由 SM 中包含的 CUDA 核心执行。线程和内核之间没有特定的映射。

  5. 如果一个 warp 包含 20 个线程,但当前只有 16 个内核可用,则该 warp 将不会运行。

  6. 另一方面,如果一个块包含 48 个线程,它将被分成 2 个 warp,如果有足够的可用内存,它们将并行执行。

  7. 如果一个线程在一个内核上启动,那么它会因内存访问或长浮点操作而停止,它的执行可能会在另一个内核上恢复。

他们是正确的吗?

现在,我有一个 GeForce 560 Ti,所以根据规格它配备了 8 个 SM,每个包含 48 个 CUDA 核心(总共 384 个核心)。

我的目标是确保架构的每个核心都执行相同的指令。假设我的代码不需要比每个 SM 中可用的更多的寄存器,我设想了不同的方法:

  1. 我创建了 8 个块,每个块有 48 个线程,因此每个 SM 有 1 个块要执行。在这种情况下,48 个线程是否会在 SM 中并行执行(利用所有可用的 48 个内核)?

  2. 如果我启动 64 个 6 个线程的块有什么区别吗?(假设它们将在 SM 之间均匀映射)

  3. 如果我将 GPU “淹没”在预定的工作中(例如,创建 1024 个块,每个块有 1024 个线程)是否可以合理地假设所有内核都将在某个点使用,并且将执行相同的计算(假设线程永不停止)?

  4. 有没有办法使用分析器检查这些情况?

  5. 这个东西有参考吗?我阅读了 CUDA 编程指南以及“大规模并行处理器编程”和“CUDA 应用程序设计与开发”中专门针对硬件架构的章节;但我无法得到准确的答案。

4

2 回答 2

139

两个最好的参考是

  1. NVIDIA Fermi 计算架构白皮书
  2. GF104 评论

我会尽力回答你的每一个问题。

程序员将工作划分为线程,将线程划分为线程块,将线程块划分为网格。计算工作分配器将线程块分配给流式多处理器 (SM)。一旦一个线程块被分配给一个 SM,线程块的资源就会被分配(warp 和共享内存)并且线程被分成 32 个线程的组,称为 warp。一旦分配了一个warp,它就被称为一个活动的warp。两个 warp 调度器每个周期选择两个活动的 warp 并将 warp 分派到执行单元。有关执行单元和指令调度的更多详细信息,请参见1 p.7-10 和2

4' . 在laneid(warp中的线程索引)和核心之间存在映射。

5' . 如果一个 warp 包含少于 32 个线程,在大多数情况下,它的执行方式与它有 32 个线程一样。由于以下几个原因,warp 的活动线程可能少于 32 个:每个块的线程数不能被 32 整除,程序执行一个发散块,因此未采用当前路径的线程被标记为不活动,或者 warp 中的线程退出。

6' . 一个线程块将被划分为 WarpsPerBlock = (ThreadsPerBlock + WarpSize - 1) / WarpSize Warp 调度程序不需要从同一个线程块中选择两个 Warp。

7' . 执行单元不会因内存操作而停止。如果当一条指令准备好被调度时资源不可用,则该指令将在未来资源可用时再次调度。Warp 可能会在障碍处、内存操作、纹理操作、数据依赖关系等方面停滞不前……停滞的 warp 没有资格被 warp 调度程序选择。在 Fermi 上,每个周期至少有 2 个符合条件的 warp 是很有用的,这样 warp 调度程序可以发出指令。

有关GTX480 和 GTX560 之间的差异,请参阅参考资料2 。

如果您阅读参考资料(几分钟),我想您会发现您的目标没有意义。我会尽力回应你的观点。

1' . 如果您启动 kernel<<<8, 48>>>,您将获得 8 个块,每个块有 2 个 32 和 16 个线程的扭曲。无法保证这 8 个块将分配给不同的 SM。如果将 2 个块分配给 SM,则每个 warp 调度程序都可以选择一个 warp 并执行该 warp。您将只使用 48 个内核中的 32 个。

2' . 8块48线程和64块6线程有很大区别。假设您的内核没有分歧,并且每个线程执行 10 条指令。

  • 8 块 48 个线程 = 16 条扭曲 * 10 条指令 = 160 条指令
  • 64 个块,6 个线程 = 64 条扭曲 * 10 条指令 = 640 条指令

为了获得最佳效率,工作分工应该是 32 个线程的倍数。硬件不会合并来自不同经线的线程。

3' . 如果内核没有最大化寄存器或共享内存,GTX560 一次可以有 8 个 SM * 8 个块 = 64 个块或 8 个 SM * 48 个扭曲 = 512 个扭曲。在任何给定时间,部分工作都将在 SM 上处于活动状态。每个 SM 都有多个执行单元(多于 CUDA 内核)。在任何给定时间使用哪些资源取决于应用程序的扭曲调度程序和指令组合。如果您不进行 TEX 操作,那么 TEX 单元将处于空闲状态。如果您不进行特殊的浮点运算,SUFU 单元将处于空闲状态。

4' . Parallel Nsight 和 Visual Profiler 展示

一个。执行IPC

湾。发行IPC

C。每个活动周期的活动经线

d。每个活动周期的合格经纱(仅限 Nsight)

e. 翘曲失速原因(仅限 Nsight)

F。每条指令执行的活动线程数

分析器不显示任何执行单元的利用率百分比。对于 GTX560,粗略估计为 IssuedIPC / MaxIPC。对于 MaxIPC 假设 GF100 (GTX480) 是 2 GF10x (GTX560) 是 4 但目标是 3 是更好的目标。

于 2012-05-06T01:21:17.657 回答
9

“E. 如果一个 warp 包含 20 个线程,但当前只有 16 个内核可用,则该 warp 将不会运行。”

是不正确的。您混淆了通常意义上的核心(也用于 CPU) - GPU 中的“多处理器”数量,nVIDIA 营销中的核心(“我们的卡有数千个 CUDA 核心”)。

一个warp本身只能被调度在一个单核(=多处理器)上,并且最多可以同时运行32个线程;它不能使用多个内核。

数字“48 warp”是具有 Compute Capability 2.x 的 nVIDIA GPU 上每个多处理器的活动 warp 的最大数量(可以选择在下一个周期,在任何给定周期内安排工作的 warp);这个数字对应于 1536 = 48 x 32 个线程。

基于此网络研讨会的答案

于 2012-10-25T12:02:40.567 回答