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

Synchronization OpenCL中是否可以进行全局同步?,synchronization,opencl,global,atomic,workgroup,Synchronization,Opencl,Global,Atomic,Workgroup,众所周知,OpenCL barrier()函数只适用于单个工作组,并且不可能直接同步工作组。如果可能的话,目前全球同步的最佳方法是什么?使用atomics、OpenCL2.0功能等 Github链接,欢迎使用示例 谢谢 内核内的全局同步是不可能的。这是因为工作组不需要同时运行。如果将内核分解成若干部分,则可以在主机应用程序中实现某种全局同步。这不适用于许多内核,尤其是在内核执行任何实际工作之前使用大量本地内存或有一点初始化代码的情况下 将内核分成两个部分——例如kernelA和kernelB。全

众所周知,OpenCL barrier()函数只适用于单个工作组,并且不可能直接同步工作组。如果可能的话,目前全球同步的最佳方法是什么?使用atomics、OpenCL2.0功能等

Github链接,欢迎使用示例


谢谢

内核内的全局同步是不可能的。这是因为工作组不需要同时运行。如果将内核分解成若干部分,则可以在主机应用程序中实现某种全局同步。这不适用于许多内核,尤其是在内核执行任何实际工作之前使用大量本地内存或有一点初始化代码的情况下

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


同样,这并不漂亮,也不一定是高性能的,但是如果你真的必须有全局同步,这是获得它的唯一方法。

虽然全局同步没有简洁的内核API调用,但是如果计算设备支持OpenCL扩展cl_khr_global_int32_base_原子,那么它可以使用原子来实现

请参阅Xiao等人的论文,该论文评估了GPU上全局同步的锁和无锁方法。


这在这里找到的另一篇stackoverflow帖子中提到:

如果为顺序处理配置了命令队列,则可以通过顺序内核的顺序来实现全局同步。 没有显式的barrier()调用,只有在kernel2之前排队的kernel1。如果命令队列配置为顺序处理,那么kernel1将在kernel2启动之前完成所有工作。您需要在两个内核之间共享一个缓冲区,以便在它们之间传递信息

订单处理是默认设置。内核之间不需要调用finish()


可以使用clCreateCommandQueueWithProperties配置命令队列,并在需要执行无序队列时,将属性设置为CL_queue_OUT_OF_ORDER_EXEC_模式。在这种情况下,需要finish()来确保同步。

在一般情况下,这是不可能的。如上所述:这是不可能的。您总是可以找到问题以适合一个工作组,并且至少具有本地同步。但当然,如果问题规模扩大,这将不再有效。如果不调整您的问题大小,它不会在不同的硬件上运行。OpenCL2.0提供了内核排队调用的特性。如果需要基于主机的同步,这可能会减少一些开销。但这并不是所有问题的通用解决方案。您可以尝试将程序划分为更多内核,并通过命令队列对其进行同步。它非常有效,特别是当您不需要记住内核中的变量并且可以计算它们时。如果您需要存储变量,那么您可以使用结构/向量的全局数组在内核之间传输变量。另一件事是,没有示例或至少没有算法描述,您正在尝试并行化,因此很难知道该怎么做。我建议再次查看该数据模式,因为如此巨大的同步是可疑的。您的问题可能有其他解决方案,或者最好使用OpenCL以外的其他解决方案。例如,SSE、多线程、OpenMP……感谢大家的宝贵意见。