3

众所周知,OpenCL barrier() 函数仅适用于单个工作组,并且没有直接同步工作组的可能性。如果可能的话,今天全球同步的最佳方法是什么?使用原子、OpenCL 2.0 功能等?

Github 链接,欢迎举例!

谢谢!

4

3 回答 3

5

内核中的全局同步是不可能的。这是因为工作组不能保证同时运行。如果您将内核分成几部分,您可以在主机应用程序中实现某种全局同步。这不适用于许多内核,特别是如果您使用大量本地内存或在内核执行任何实际工作之前有一些初始化代码。

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

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

于 2015-05-17T17:09:59.060 回答
4

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

请参阅 Xiao 等人的论文,该论文评估了 GPU 上全局同步的锁和无锁方法。 http://synergy.cs.vt.edu/pubs/papers/xiao-ipdps2010-gpusync.pdf

这在此处找到的另一篇 stackoverflow 帖子中提到:OpenCL 和 GPU 全局同步

于 2016-03-22T20:21:43.693 回答
0

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

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

如果需要乱序队列执行,可以使用 clCreateCommandQueueWithProperties 配置命令队列并将属性设置为 CL_QUEUE_OUT_OF_ORDER_EXEC_MODE。在这种情况下,将需要完成()来确保同步。

于 2020-08-04T12:25:47.223 回答