CUDA共享内存原子哪个更快——扭曲局部性还是反局部性



假设一个(CUDA内核网格(块中的许多扭曲正在重复更新大小适中的共享内存位置。

在哪种情况下,此类工作会更快完成?:

  1. 曲速内访问的情况locality,例如每个曲速访问的内存位置总数很小,其中大多数确实由多个通道访问
  2. 访问反位置的情况下,所有通道通常访问不同的位置(可能是为了避免银行冲突(

同样重要的是,这个微体系结构是依赖于它的,还是在所有最近的NVIDIA微体系结构上基本相同?

反本地化访问将更快

在SM5.0(Maxwell(及以上的GPU上,共享内存原子(假设添加(由于地址冲突(具有相同地址的两个通道(,共享内存单元将重放指令。正常的银行冲突回放也适用。在Maxwell/Pascal上,共享内存单元在两个SM分区之间具有固定的循环访问(每个分区中有2个调度器(。对于每个分区,共享内存单元将在转移到下一条指令之前完成该指令的所有重放。Volta SM将在任何其他共享内存指令之前完成该指令。

  1. 避免银行冲突
  2. 避免地址冲突

在费米和开普勒体系结构上,必须在读取-修改-写入操作之前执行共享内存锁定操作。这阻止了所有其他扭曲指令。

感谢费米/开普勒,Maxwell和更新的GPU具有显著更快的共享存储器原子性能。

可以编写一个非常简单的内核来对两种不同的情况进行微基准测试。CUDA评测器为共享内存访问提供指令执行计数和重放计数,但不区分由于原子学引起的重放和由于加载/存储冲突或矢量访问引起的重放。

即使不需要知道共享内存原子是如何在CUDA硬件中实现的,也可以提出一个非常简单的论点:归根结底,原子操作必须以某种方式在的某个点序列化。一般来说,这是真的,你在哪个平台或硬件上运行并不重要。原子性本质上需要这一点。如果并行发布了多个原子操作,则必须以确保原子性的方式执行它们。这意味着,无论我们谈论的是GPU还是CPU,原子操作总是会随着争用的增加而变慢。唯一的问题是:多少。这取决于具体的执行情况。

因此,通常情况下,您希望尽可能降低争用级别,即试图并行对同一内存位置执行原子操作的线程数…

这是一个推测性的部分答案。

考虑相关的问题:共享内存上原子操作的性能及其公认的答案。

如果那里被接受的答案是正确的(即使在今天仍然是正确的(,那么在更本地化的访问中,翘曲线程将相互阻碍,使许多通道的原子操作更慢,即使翘曲原子的反局部性更好。

但老实说,我不确定我是否完全同意这一论点,也不知道自从写下答案以来,情况是否发生了变化。

最新更新