1

我是学习CUDA并行编程的菜鸟。现在我对设备的全局内存访问感到困惑。这是关于翘曲模型和合并的。

有几点:

  1. 据说一个块中的线程被分成经线。在每个经纱中最多有 32 个线程。这意味着同一个warp的所有这些线程将在同一个处理器上同时执行。那么半曲折的意义是什么?

  2. 当涉及到一个块的共享内存时,它会被分成16个bank。为了避免银行冲突,多个线程可以同时读取一个银行,而不是写入同一个银行。这是一个正确的解释吗?

提前致谢!

4

1 回答 1

5
  1. “half-warp”的主要用法是在 Fermi 一代之前应用于 CUDA 处理器(例如“Tesla”或 GT200 一代,以及最初的 G80/G92 一代)。 这些 GPU 采用 SM(流式多处理器 - GPU 内部的一个硬件块)构建而成,具有少于 32 个线程处理器。经线的定义仍然相同,但实际的硬件执行一次发生在“半经线”中。实际上,粒度细节比这更复杂,但只要说执行模型导致内存请求根据半扭曲的需要发出就足够了,即扭曲内的 16 个线程。因此,命中内存事务的完整 warp 将为该事务生成总共 2 个请求。

    Fermi 和更新的 GPU 每个 SM 至少有 32 个线程处理器。因此,内存事务在整个 warp 中是立即可见的。因此,内存请求是在 per-warp 级别发出的,而不是 per-half-warp。但是,一个完整的内存请求一次只能检索 128 个字节。因此,对于每个事务的每个线程大于 32 位的数据大小,内存控制器仍可能将请求分解为半扭曲大小。

    我的观点是,特别是对于初学者来说,没有必要对半翘曲有详细的了解。通常理解它是指一组 16 个线程一起执行就足够了,它对内存请求有影响。

  2. 例如,费米级 GPU上的共享内存 分为 32 个组。在以前的 GPU 上 ,它被分成 16 个组。在同一内存请求中(即源自同一代码指令)中,只要一个单独的银行被多个线程访问,就会发生银行冲突。为了避免银行冲突,基本策略与合并内存请求的策略非常相似,例如。用于全局内存。在 Fermi 和更新的 GPU 上,多个线程可以读取同一个地址而不会导致 bank 冲突,但一般来说,bank 冲突的定义是多个线程从同一个 bank 中读取。为了进一步了解共享内存以及如何避免银行冲突,我建议关于此主题的NVIDIA 网络研讨会
于 2013-02-18T00:03:12.980 回答