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

Edu*_*eis 0 cuda

我对 CUDA 编程比较陌生。

在这篇博客(如何在 CUDA C/C++ 内核中高效访问全局内存)中,我们有以下内容:

“该设备可以通过与其大小对齐的 32、64 或 128 字节事务来访问全局内存。”

这篇文章中也提到了128字节事务(CUDA全局内存事务的成本

此外,《CUDA C 编程指南》中还提到了 32 字节和 128 字节内存事务。本指南还显示了图 20 有关对齐和未对齐访问的信息,但我不太理解。


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

Rob*_*lla 8

这两者都需要在 CUDA warp的背景下理解。所有操作都是在扭曲范围内发出的,这包括访问内存的指令。

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

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

该图描述了扭曲中每个线程的行为。它们分别由向上的灰色/黑色箭头表示。每个箭头代表来自线程的请求,并且箭头指向该线程想要加载或存储的内存中的相对位置。

这些图表相互比较以显示“对齐”的效果。当考虑扭曲宽度时,如果所有 32 个线程都请求属于单个段的数据字节,则这将要求内存控制器仅检索一个段来满足请求。对于单个请求(即单个加载或存储指令) ,这可以说是最有效的可能行为(因此数据组织以及访问模式,被认为是扭曲范围)。

然而,如果从扭曲中的每个线程发出的地址导致第二张图所示的模式,这将是“未对齐的”,并且即使您有效地要求类似的数据“足迹”,缺乏与单个数据的对齐段意味着内存控制器需要从内存中检索 2 个段才能满足请求。

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

为了更完整、有序地处理这些主题,我建议参考各种培训材料。它绝不是唯一的一个,但本培训系列的第 4 单元将更详细地介绍该主题。