OpenCL和CUDA已经包含了几年的原子操作(尽管显然不是每个CUDA或OpenCL设备都支持这些)。但是 - 我的问题是关于"和#34;生活在一起的可能性。由非原子写入引起的比赛。
假设网格中的多个线程都写入全局内存中的相同位置。我们是否保证,当内核执行结束时,其中一个写入的结果将出现在该位置,而不是一些垃圾?
此问题的相关参数(选择任何组合,编辑,但已获得答案的nVIDIA + CUDA除外):
答案 0 :(得分:6)
我们是否保证,当内核执行结束时,其中一个写入的结果将出现在该位置,而不是某些垃圾?
对于CUDA GPU,我非常确定使用OpenCL的NVIDIA GPU,答案是肯定的。我下面的大多数术语都会有CUDA。如果您需要CUDA和OpenCL的详尽答案,请告诉我,我将删除此答案。无论如何,Very similar questions to this one已经被问到并回答了。 Here's another,我确定还有其他人。
当多个"同时"写入发生在同一位置,其中一个将赢得完整。
哪一个将获胜是未定义的。非获胜写入的行为也是未定义的(它们可能会发生,但可能会被胜利者取代,或者根本不会发生。)内存位置的实际内容可能会通过各种值(例如原始值) ,加上任何有效的书面价值),但过境不会通过"垃圾"价值(即尚未存在且未被任何线程写入的价值。)过境终止于"赢家",最终。
示例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编程原则,例如naturally aligned traffic对设备内存位置的要求。我在这里看到的事务是源自单个SASS指令的事务(每个线程)这样的事务可以具有1,2,4,8或16个字节的宽度。我在这里提出的权利要求适用于写入是否源自"同一行代码"或者"不同的行"。
这是一个相当复杂的主题(特别是当我们考虑缓存行为时,以及当我们在混合中抛出读取时会发生什么),但是" junk"值永远不会发生。在全局内存中应该出现的唯一值是那些开始的值,或某些线程在某处写入的值。