在OpenCL中,与barrier()相反,mem_fence()做什么?

在OpenCL中,与barrier()相反,mem_fence()做什么?,opencl,gpgpu,memory-barriers,barrier,memory-fences,Opencl,Gpgpu,Memory Barriers,Barrier,Memory Fences,与barrier()(我想我能理解)不同,mem\u fence()不会影响工作组中的所有项目。OpenCL规范(第6.11.10节)针对mem\u fence(): 命令加载和存储执行内核的工作项 (因此它适用于单个工作项) 但同时,在第3.3.1节中,它指出: 在工作项中,内存具有加载/存储一致性 因此,在一个工作项中,内存是一致的 那么mem\u fence()对什么有用呢?它不能跨项目工作,但在项目中不需要它 请注意,我没有使用原子操作(第9.5节等)。mem\u fence()是否与这

barrier()
(我想我能理解)不同,
mem\u fence()
不会影响工作组中的所有项目。OpenCL规范(第6.11.10节)针对
mem\u fence()

命令加载和存储执行内核的工作项

(因此它适用于单个工作项)

但同时,在第3.3.1节中,它指出:

在工作项中,内存具有加载/存储一致性

因此,在一个工作项中,内存是一致的

那么
mem\u fence()
对什么有用呢?它不能跨项目工作,但在项目中不需要它

请注意,我没有使用原子操作(第9.5节等)。
mem\u fence()
是否与这些结合使用?如果是这样的话,我想看一个例子

谢谢


更新:我可以看出它与
barrier()
一起使用时是多么有用(隐式地,因为barrier调用
mem\u fence()
)-但肯定还有更多,因为它是单独存在的?

尝试更清楚地表达它(希望如此)

mem_fence()
等待,直到工作组中的所有线程都可以看到调用工作项在mem_fence()之前对本地和/或全局内存进行的所有读/写操作

这来自:

内存操作可以重新排序,以适应其运行的设备。规范规定(基本上)任何内存操作的重新排序都必须确保内存在单个工作项中处于一致状态。但是,如果您(例如)执行存储操作,并且value决定暂时驻留在特定于工作项的缓存中,直到出现更好的时间写入本地/全局内存,该怎么办?如果尝试从该内存加载,则写入该值的工作项将其保存在其缓存中,因此没有问题。但是工作组中的其他工作项没有,因此它们可能读取错误的值。放置内存围栏可确保在调用内存围栏时,本地/全局内存(根据参数)将保持一致(任何缓存都将被刷新,任何重新排序都将考虑到您期望其他线程在此之后可能需要访问此数据)

我承认这仍然令人困惑,我不会发誓我的理解是100%正确的,但我认为这至少是总体思路

跟进:

我找到了这个关于CUDA内存围栏的链接,但OpenCL也有同样的想法:

查看章节B.5内存围栏功能

他们有一个代码示例,可以在一次调用中计算数字数组的和。代码设置为在每个工作组中计算部分和。然后,如果还有更多的求和工作要做,代码会让最后一个工作组来做

所以,每个工作组基本上要做两件事:一个部分和,它更新一个全局变量,然后是一个计数器全局变量的原子增量

之后,如果还有更多的工作要做,则将计数器增加到值(“工作组大小”-1)的工作组将被视为最后一个工作组。该工作组将继续完成

现在,问题(正如他们所解释的)在于,由于内存重新排序和/或缓存,计数器可能会增加,最后一个工作组可能会在部分和全局变量的最新值写入全局内存之前开始工作

内存围栏将确保在移动通过围栏之前,所有线程的部分和变量的值都是一致的


我希望这有点道理。这是令人困惑的。

围栏确保在围栏之前发出的负载和/或存储将在围栏之后发出的任何负载和/或存储之前完成。围栏本身并不意味着sinc。屏障操作支持在一个或两个内存空间中设置读/写围栏,并在给定者工作组中的所有工作项到达之前进行阻塞

这就是我对它的理解(我仍在尝试验证)

memory\u fence
只会确保组中所有线程的内存一致且可见,即执行不会停止,直到出现另一个内存事务(本地或全局)。这意味着如果在
内存限制
之后有移动指令或添加指令,设备将继续执行这些“非内存事务”指令

另一方面,屏障将停止执行,句号为。只有在所有线程到达该点并且所有内存事务都已清除后,才会继续


换句话说,
barrier
mem\u fence
的超集
barrier
在性能方面可能比
mem\u fence

更昂贵,但在您给出的示例中,另一个线程无法确保数据在没有屏障的情况下存储。所以你还是需要障碍物。我想我没有在最初的问题中提到这一点,但我不明白mem_fence单独使用(当不与屏障一起使用时)有什么意义。抱歉,如果我遗漏了什么,谢谢你的评论…我在上面添加了更多细节。我希望这能有所帮助。好吧,cuda的例子中包含了一个原子操作,我怀疑这是mem_fence发挥作用所必需的。为了将来的参考,这里描述了opencl和cuda函数之间的等价性——虽然您可能在描述opencl men_fence()的意图或从类似的cuda函数中推断,但我认为原始海报的问题仍然没有得到回答。men_fence()的OpenCL规范,即使是现在的1.2版本,也没有说它提供了工作组中线程之间的一致性。我还有一个相同的问题,为什么要有男人?AMD论坛上的这个帖子提供了一个与这个答案相矛盾的解释和使用示例。本演示文稿证明