对GPU上的非原子写入的弱保证?

ein*_*ica 4 cuda atomic memory-model opencl atomicity

OpenCL和CUDA已经包含了几年的原子操作(尽管显然不是每个CUDA或OpenCL设备都支持这些).但是 - 我的问题是由于非原子写作而与"生活在一起"比赛的可能性.

假设网格中的多个线程都写入全局内存中的相同位置.我们是否保证,当内核执行结束时,其中一个写入的结果将出现在该位置,而不是一些垃圾?

这个问题的相关参数(选择任何组合,编辑除了已经得到答案的nVIDIA + CUDA):

  • 内存空间:仅限全局内存; 这个问题与本地/共享/私人记忆无关.
  • 对齐:在单个存储器写入宽度内(例如,nVIDIA GPU上的128位)
  • GPU制造商:AMD/nVIDIA
  • 编程框架:CUDA/OpenCL
  • 存储指令在代码中的位置:所有线程/不同代码行的相同代码行.
  • 写入目标:固定地址/固定偏移量与功能参数的地址/完全动态
  • 写宽度:8/32/64位.

Rob*_*lla 8

我们是否保证,当内核执行结束时,其中一个写入的结果将出现在该位置,而不是一些垃圾?

对于CUDA GPU,我很确定使用OpenCL的NVIDIA GPU,答案是肯定的.我下面的大多数术语都会有CUDA.如果您需要CUDA和OpenCL的详尽答案,请告诉我,我将删除此答案. 在此之前,已经提出并回答了与此问题非常相似的问题. 这是另一个,我相信还有其他人.

当多个"同时"写入发生在同一位置时,其中一个将完好无损地获胜.

哪一个将获胜是未定义的.非获胜写入的行为也是未定义的(它们可能会发生,但可能会被胜利者取代,或者根本不会发生.)内存位置的实际内容可能会通过各种值(例如原始值) ,加上任何有效的书面价值),但过境不会通过"垃圾"值(即不存在的值,也不是任何线程所写的.)最终,过境终止于"胜利者".

例1:

位置X包含零.线程1,5,32,30000和450000都写入该位置.如果该位置没有其他写入流量,则该位置最终将包含值1(在内核终止时或更早).

例2:

位置X包含5.线程32将1写入X.线程90303将7写入X.线程432322将972写入X.如果没有其他写入流量到该位置,则在内核终止时或更早,位置X将包含1 ,7或972.它不包含任何其他值,包括5.

我假设X在全局内存中,并且它的所有流量自然与它对齐,并且它的所有流量都具有相同的大小,尽管这些原则也适用于共享内存.我还假设您没有违反CUDA编程原则,例如对设备内存位置的自然对齐流量的要求.我在这里看到的事务是源自单个SASS指令的事务(每个线程)这样的事务可以具有1,2,4,8或16个字节的宽度.我在这里提出的权利要求适用于写入是来自"相同的代码行"还是"不同的行".

这是一个相当复杂的主题(特别是当我们考虑缓存行为时,以及当我们在混合中抛出读取时会发生什么),但是"垃圾"值永远不会发生.在全局内存中应该出现的唯一值是那些开始的值,或某些线程在某处写入的值.