【问题标题】:How to execute atomic write in CUDA?如何在 CUDA 中执行原子写入?
【发布时间】:2019-12-22 04:32:33
【问题描述】:

首先,无论写入是否在 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

【问题讨论】:

  • 原子操作,如文档所述,在 CUDA 中是“读-修改-写操作”。用于 CUDA 的定义是“操作是原子的,因为它保证在不受其他线程干扰的情况下执行”。我认为(不是 100% 确定)你可以确保在你展示的代码中得到 1,2,你只是不知道是哪个内核写的,因为竞争条件
  • @AnderBiguri,你引用我链接的部分吗?如果是,则句子的开头说明了 functions 而不是 operations,因此我相信这个 read-modify-write 应该是读取一个序列而不是一个池,他们指的是到下面列出的功能(在文档中)。
  • 不,你不能得到 3,你会得到 1 或 2,假设你正在做的写入在位置上是一致的并且在线程之间自然对齐,这已经在其他地方讨论过(这里有多个问题在cuda 标签上,例如this one)您的问题可能与该问题重复。
  • 如果你想要一个关于 CUDA 内存一致性模型的正式声明,而不是我的声明,你需要解析 the memory model definition given in the PTX manual
  • @RobertCrovella,谢谢,但我检查了你的答案,一旦你写了写是原子的,在你写的另一个答案上写不是原子的。首先,写不能同时是原子的和非原子的,其次,有这样的矛盾我仍然不知道它们是否是原子的:-)

标签: cuda atomic


【解决方案1】:

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

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

那么,考虑到写入的数据类型大小,您可以保证获得这两个线程写入的值之一,而不是任何其他值。只要写入由单个 SASS 指令完成,就可以提供此功能。此处提供正确性by current CUDA hardware,不一定是编译器、CUDA 编程模型和/或 CUDA 所遵循的 C++ 标准。

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

这假定没有其他线程对写入的位置执行“任何其他”操作(即,它们没有向该位置或任何重叠位置或其他对齐方式写入不同大小的数量)。

除非程序员对操作强制执行某种排序,否则哪个实际值最终会出现在该位置通常是未定义的(除了它将是一个且只有一个写入值,而不是其他任何值)。

在 C/C++ 中编写向量或结构时,应注意确保 SASS 代码中的底层写入(存储)指令引用适当的大小。上面提到的写操作时的 cmets 是指由 SASS 代码发出的写操作。一般来说,我认为这种解释与使用 POD 数据类型的“从 C/C++ 代码写入”之间不会有太大区别。但是结构可能会被分解成多个较小规模的交易,在这种情况下,上述陈述将被废除。不过,在 C/C++ 中通过适当的编程实践(例如,谨慎使用向量类型),可以确保在相关的情况下最多使用 8 个字节的写入。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-27
    • 2021-04-17
    • 1970-01-01
    • 2010-12-30
    • 2019-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多