Cuda 对于GPU扭曲,哪种原子瞄准模式更好:完全相同还是完全不同?

Cuda 对于GPU扭曲,哪种原子瞄准模式更好:完全相同还是完全不同?,cuda,opencl,gpgpu,atomic,Cuda,Opencl,Gpgpu,Atomic,假设我们有: 单经纱(32线) 每个线程t有32个int值val t,0…val t,31 每个值val t,i需要原子地添加到变量desti中,该变量位于(选项1)全局设备内存(选项2)共享块内存中 哪种访问模式可以更快地执行这些添加: 所有线程都将val t,1添加到dest 1 所有线程都将val t、2添加到dest 2 等等 每个具有索引t的线程都将val t,t写入dest t 每个带有索引t的线程将val t(t+1)mod 32写入dest(t+1)mod 32 等等 换句话

假设我们有:

  • 单经纱(32线)
  • 每个线程t有32个int值val t,0…val t,31
  • 每个值val t,i需要原子地添加到变量desti中,该变量位于(选项1)全局设备内存(选项2)共享块内存中
哪种访问模式可以更快地执行这些添加:

  • 所有线程都将val t,1添加到dest 1

    所有线程都将val t、2添加到dest 2

    等等

  • 每个具有索引t的线程都将val t,t写入dest t

    每个带有索引t的线程将val t(t+1)mod 32写入dest(t+1)mod 32

    等等

  • 换句话说,当一个warp的所有线程在同一个周期中进行原子写入时,是更快,还是没有原子写入重合更好?我可以想出硬件来更快地执行这两个选项,我想知道实际实现了什么

    想法:

    • GPU有可能拥有将多个原子操作从同一个扭曲集中到一个目的地的硬件,这样它们实际上只算一个,或者至少可以一起调度,因此所有线程将同时执行下一条指令,不要等到所有其他的事情都做完了,最后一次原子行动才结束
    注意事项:

    • 这个问题的重点是英伟达与CUDA的硬件,但我希望得到有关AMD和其他GPU的答案
    • 不管线程是如何得到它们的。假设它们在寄存器中并且没有溢出,或者它们是在寄存器中完成的一些算术运算的结果。忘记任何获取它们的内存访问

      • 我就是这样理解您的问题的:

        您有一个32x32整数矩阵:

        Val0'0,Val1'0,…Val31'0
        Val1'0,Val1'1,…Val31'1
        .
        .
        Val31'0,Val31'1,…,Val31'31

        您需要对每一行求和:
        Val0'0+Val1'0+。。。Val31'0=dest0
        Val0'1+Val1'1+。。。Val31'1=dest1等

        问题是您的行值分布在不同的线程之间。 对于单个扭曲,最干净的方法是让每个线程使用共享内存(在32x32共享内存阵列中)共享其值。线程同步后,线程i对第i行求和,并将结果写入dest(i),dest(i)可以驻留在全局或共享内存中(取决于您的应用程序)。 通过这种方式,计算工作量(31x31)的增加在扭曲中的线程之间平均分配,您根本不需要原子操作(性能杀手)。
        根据我的经验,原子操作通常可以而且应该通过线程之间不同的工作分配来避免。

        虽然我不知道确切的答案,但我的猜测是倾斜访问更可取。在理想情况下,每个周期至少要执行32个原子操作,但在实际硬件中,您的算法可能会遇到内存访问模式不好的问题。这听起来像是只有通过仔细的基准测试才能解决的问题。是什么阻止了你尝试它?@Talonmes:1。我只有一张(或者两张)卡片可以用来做基准测试。2.答案可能是“这可能取决于其他参数”,在这种情况下,我会考虑它们。3.对于我正在研究的实际问题,我试图减少原子的使用,而不是优化itI,我将使用第二个。第一个访问模式在所有车道的每个循环中具有相同的地址。当共享内存是目标时,这尤其会降低Maxwell之前的CUDA卡的性能(请参阅)。也请看一下和。