如何在CUDA中执行原子写入?

时间:2018-10-17 06:20:35

标签: cuda atomic

首先,无论写入是否在CUDA中是原子的,我都无法找到可靠的来源。例如Is global memory write considered atomic in CUDA?触及了这个主题,但最后一句话表明我们不是在谈论相同的原子概念。拥有代码:

global_mem[0] = pick_at_random_from(1, 2);
shared_mem[0] = pick_at_random_from(1, 2);

由成千上万个线程执行,“原子”表示在两种情况下内容均为1或2,并保证其他任何内容都不会出现(如3)。原子意味着完整性。

但是据我了解,CUDA不能保证它,因此当我运行此代码时,我可能会得到值3?如果确实如此,如何执行原子写入?有atomicExch,但这是一个过大的杀伤力,它的作用超出了所需。

我已经检查过的

原子功能:https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#atomic-functions

1 个答案:

答案 0 :(得分:2)

对于在CUDA中2个不同线程中的每个线程中的写操作,如果:

  • 写入内容在同一位置(地址)
  • 该地址的大小为naturally aligned
  • 两个线程之间的写入操作大小相同(大小分别为1、2、4、8或16个字节)

然后,考虑到已写入的数据类型大小,可以确保得到这两个线程写入的值之一,而不是其他任何值。

这可以直接扩展到满足上述条件的任意数量的线程。

假设没有其他线程针对写入的位置做“其他任何事情”(即,它们没有在该位置,任何重叠的位置或其他对齐方式中写入不同的大小数量)。

除非程序员对操作强制执行一些排序,否则实际值通常会在该位置最终终止(除非它将是一个且只有一个写入值,而不是其他任何值)。

在用C / C ++编写向量数量或结构时,应注意确保SASS代码中的基础写(存储)指令引用了适当的大小。上面提到写操作时的注释是指SASS代码发出的写操作。一般来说,我不希望这种解释与使用POD数据类型的“从C / C ++代码写入”之间有太大区别。但是结构可能会分解为多个较小的事务,在这种情况下,可以取消上述声明。尽管如此,在C / C ++中通过适当的编程实践(例如,谨慎使用向量类型),有可能确保使用8或16字节的写操作。