OpenCL中是否可能进行全局同步?

3
众所周知,OpenCL的barrier()函数仅适用于单个工作组,并且没有直接同步工作组的可能性。如果可能的话,今天最好的全局同步方法是什么?使用原子操作、OpenCL 2.0功能等等?欢迎提供Github链接和示例!
谢谢!

2
一般情况下,这是不可能的。 - user703016
如上所述:这是不可能的。您始终可以找到适合一个工作组并具有至少本地同步的问题。但是,当然,如果问题规模扩大,这将不再起作用。而且,如果不调整问题大小,它将无法在不同的硬件上运行。OpenCL 2.0提供了内核排队调用的功能。如果需要基于主机的同步,则可能会减少一些开销。但这不是所有类型问题的通用解决方案。 - Christian
你可以尝试将程序分成更多的内核,并通过命令队列进行同步。这在你不需要记住内核中的变量并且可以计算它们时非常有效。如果你需要存储变量,那么你可以使用全局结构/向量数组来在内核之间传输变量。 - blind.wolf
另一件事是,你试图并行化的算法没有示例或至少描述,所以很难说该怎么做。我建议再次查看数据模式,因为如此巨大的同步是可疑的。你的问题可能有另一个解决方案,或者最好使用OpenCL之外的其他东西。例如SSE、多线程、OpenMP等。 - blind.wolf
感谢大家提供的好建议。 - ash
3个回答

5

在内核中进行全局同步是不可能的,这是因为工作组不能保证同时运行。如果您将内核分成多个部分,则可以在主机应用程序中实现某种形式的全局同步。这对于许多内核来说并不适用,尤其是如果您使用了大量本地内存或者在内核执行任何真正的工作之前需要有一些初始化代码。

将内核分成两部分--例如kernelA和kernelB。全局同步只需运行kernelA的NDRange,然后finish(),再运行kernelB的NDRange即可。全局数据将在两次调用之间保留在内存中。

再次说明,这并不是很美观,也不一定高性能,但如果您确实需要全局同步,这是唯一的方法。


4

0
如果一个命令队列被配置为按顺序处理,全局同步可以通过顺序内核来实现。没有显式的barrier()调用,只有kernel1在kernel2之前入队。如果命令队列被配置为按顺序处理,kernel1将在kernel2开始之前完成所有工作。您需要在两个内核之间共享缓冲区以传递信息。
按顺序处理是默认的。在内核之间不需要调用finish()。
命令队列可以通过clCreateCommandQueueWithProperties进行配置,并将属性设置为CL_QUEUE_OUT_OF_ORDER_EXEC_MODE,如果需要无序队列执行。在这种情况下,需要使用finish()来确保同步。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接