什么是 CUDA 全局内存 32、64 和 128 字节事务?

What are CUDA Global Memory 32-, 64- and 128-byte transactions?

我对 CUDA 编程比较陌生。

在此博客 (How to Access Global Memory Efficiently in CUDA C/C++ Kernels) 中,我们有以下内容:

"The device can access global memory via 32-, 64-, or 128-byte transactions that are aligned to their size."

这个post(The cost of CUDA global memory transactions)

中也提到了128字节的事务

此外,CUDA C Programming Guide中还提到了32字节和128字节的内存事务。本指南还显示了关于对齐和未对齐访问的图 20,我不太明白。


  1. 解释并举例说明 32、64、128 字节的事务是如何发生的?
  2. 更详细地查看图 20。该图的意义何在?

这两个都需要在 CUDA warp 的上下文中理解。发出所有操作 warp-wide,其中包括访问内存的指令。

单个 CUDA 线程 can access 单个指令或事务中的 1、2、4、8 或 16 个字节。当考虑 warp-wide 时,这会一直转换为 32 字节到 512 字节。 GPU 内存控制器通常可以以 32 字节到 128 字节的粒度向内存发出请求。较大的请求(例如,512 字节,被认为是 warp 宽度)将通过通常不超过 128 字节的多个“事务”发出。

现代 DRAM 内存的设计特点是您通常不要求单个字节,对于典型的 GPU 设计,您通常一次要求一个 32 字节的“段”。将内存划分为段是在设计时固定的。因此,您可以请求前 32 个字节(第一个段)或后 32 个字节(第二个段)。例如,您不能请求字节 16-47。这都是 DRAM 设计的一个功能,但它体现在内存行为方面。

图表描述了 warp 中每个线程的行为。单独地,它们由指向上方的 gray/black 箭头表示。每个箭头代表来自线程的请求,箭头指向该线程要加载或存储的内存中的相对位置。

这些图表是相互比较的,以显示“对齐”的效果。当考虑 warp-wide 时,如果所有 32 个线程都请求属于单个段的数据字节,这将需要内存控制器仅检索一个段来满足请求。这可以说是最有效的行为(因此数据 organization 以及 access pattern,被认为是 warp-wide)请求(即单个加载或存储指令)。

然而,如果从 warp 中的每个线程发出的地址导致第 2 个图中描述的模式,这将是“未对齐的”,即使您有效地要求类似的数据“足迹”,也缺乏对齐到单个段意味着内存控制器将需要从内存中检索 2 个段以满足请求。

这是理解图中的重点。但故事远不止于此。未对齐的访问不一定像这可能暗示的那样悲惨(性能减半)。 GPU 缓存在这里发挥作用,当我们不仅在单个 warp 的上下文中考虑这些事务时,而且在多个 warp 中考虑这些事务。

为了更完整有序地处理这些主题,我建议参考各种培训material。这绝不是唯一的,但 this training series 的第 4 单元将更详细地介绍该主题。