如何在 CUDA 中执行原子写入?
How to execute atomic write in CUDA?
首先,无论写入在 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);
由大量线程执行 "atomic" 意味着在这两种情况下,内容都是 1 或 2,并且保证不会出现其他任何内容(如 3)。原子意味着完整性。
但据我了解,CUDA 不保证它,所以当我 运行 这段代码时,我可能会得到值 3?如果真的是这样,如何执行原子写?有 atomicExch
但它有点矫枉过正 -- 它做的比需要的多。
我已经检查过的原子函数:https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#atomic-functions
对于 CUDA 中 2 个不同线程中的每一个的写入操作,如果:
- 写入到相同的位置(地址)
- 对于写入的大小,该地址是 naturally aligned
- 两个线程中每个线程的写操作大小相同(大小为 1、2、4 或 8 字节)
那么考虑到写入的数据类型大小,您一定会得到这两个线程写入的值之一,而不是任何其他值。只要写入是由单个 SASS 指令完成的,就会提供此信息。这里的正确性是提供by current CUDA hardware,不一定是编译器,CUDA编程模型,and/orCUDA遵循的C++标准
这可以直接扩展到满足上述条件的任意数量的线程。
这假定没有其他线程正在对写入的位置执行 "anything else"(即,它们没有向该位置、任何重叠位置或其他对齐方式写入不同大小的数量)。
哪个实际值最终会出现在该位置通常是未定义的(除非它将是一个且仅是一个写入值,而不是其他任何值),除非程序员对操作强制执行某种顺序。
在 C/C++ 中编写向量或结构时,应注意确保 SASS 代码中的底层写入(存储)指令引用适当的大小。上面提到写操作时的注释是指 SASS 代码发出的写操作。一般来说,我不希望这种解释与使用 POD 数据类型的 "writes from C/C++ code" 有太大区别。但是结构可能会被分解成多个更小的事务,在这种情况下,上述陈述将被废除。尽管如此,在 C/C++ 中通过适当的编程实践(例如谨慎使用向量类型)是可能的,以确保在相关时最多使用 8 字节写入。
首先,无论写入在 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);
由大量线程执行 "atomic" 意味着在这两种情况下,内容都是 1 或 2,并且保证不会出现其他任何内容(如 3)。原子意味着完整性。
但据我了解,CUDA 不保证它,所以当我 运行 这段代码时,我可能会得到值 3?如果真的是这样,如何执行原子写?有 atomicExch
但它有点矫枉过正 -- 它做的比需要的多。
我已经检查过的原子函数:https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#atomic-functions
对于 CUDA 中 2 个不同线程中的每一个的写入操作,如果:
- 写入到相同的位置(地址)
- 对于写入的大小,该地址是 naturally aligned
- 两个线程中每个线程的写操作大小相同(大小为 1、2、4 或 8 字节)
那么考虑到写入的数据类型大小,您一定会得到这两个线程写入的值之一,而不是任何其他值。只要写入是由单个 SASS 指令完成的,就会提供此信息。这里的正确性是提供by current CUDA hardware,不一定是编译器,CUDA编程模型,and/orCUDA遵循的C++标准
这可以直接扩展到满足上述条件的任意数量的线程。
这假定没有其他线程正在对写入的位置执行 "anything else"(即,它们没有向该位置、任何重叠位置或其他对齐方式写入不同大小的数量)。
哪个实际值最终会出现在该位置通常是未定义的(除非它将是一个且仅是一个写入值,而不是其他任何值),除非程序员对操作强制执行某种顺序。
在 C/C++ 中编写向量或结构时,应注意确保 SASS 代码中的底层写入(存储)指令引用适当的大小。上面提到写操作时的注释是指 SASS 代码发出的写操作。一般来说,我不希望这种解释与使用 POD 数据类型的 "writes from C/C++ code" 有太大区别。但是结构可能会被分解成多个更小的事务,在这种情况下,上述陈述将被废除。尽管如此,在 C/C++ 中通过适当的编程实践(例如谨慎使用向量类型)是可能的,以确保在相关时最多使用 8 字节写入。