【问题标题】:Is global synchronization in OpenCL possible?OpenCL 中的全局同步是否可行?
【发布时间】:2015-07-24 10:56:27
【问题描述】:

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

Github 链接,欢迎举例!

谢谢!

【问题讨论】:

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

标签: synchronization opencl global atomic workgroup


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

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

    这里的另一个 stackoverflow 帖子中提到了这一点:OpenCL and GPU global synchronization

    【讨论】:

      【解决方案3】:

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

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

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

      【讨论】:

        猜你喜欢
        • 2014-07-21
        • 1970-01-01
        • 2020-01-04
        • 1970-01-01
        • 2018-07-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多