【问题标题】:OpenCL work-items per work-groups in a 2DRange2DRange 中每个工作组的 OpenCL 工作项
【发布时间】:2016-04-23 01:40:27
【问题描述】:

这段代码here代表矩阵乘法,代码使用OpenCL编写。三个矩阵(2 in - 1out)的大小为 1024x1024。

谈到 OpenCL 实现,执行范围是二维的,所以我们有 1024x1024 个工作组,每个工作组由 16x16 个工作项组成。

问题是,为什么我们要设置每个工作组的大小,因为在内核中我们既不使用本地内存也不使用 get_local_id() 调用?将工作组维度设置为空不会更好,以便每个工作组都致力于填充输出矩阵的每个单元格?

对我来说,阅读内核代码(在我链接的页面底部),似乎每个工作组都准备好使用 16x16 工作项,但最后它们仍然未使用。我会将本地大小设置为 NULL。为什么他们使用 16x16,有什么改进?我很困惑。

【问题讨论】:

    标签: c opencl gpu


    【解决方案1】:

    在 clEnqueueNDRange 中设置本地工作大小只是为了告诉 OpenCL 设备尝试对来自全局工作组的工作项进行分组以利用并行性。如果您将其保留为 null,那么 OpenCL 将选择适当的本地工作大小并执行您的内核。理想情况下,全局工作大小应该可以被本地工作大小整除,并且本地工作大小应该是设备上计算单元数量的整数倍。因此,即使您将本地工作大小设为 null,我猜 OpenCL 仍会选择适当的值并并行启动计算。 我已经看到将本地工作大小设置为 null 会使我的代码运行得比实际在此处提供值更快的情况。

    P.S.: - 我还是 OpenCL 的菜鸟,如有小错误请见谅。

    【讨论】:

      【解决方案2】:

      问题是,为什么我们要设置每个工作组的大小,因为在内核中我们既不使用本地内存也不使用 get_local_id() 调用?将工作组维度设置为空不是更好,以便每个工作组都可以填充输出矩阵的每个单元格吗?

      没错,我们没有使用本地内存或get_local_id()。但是,您的工作组的大小以及您决定启动多少个工作组决定了并行执行的整个计算域(在 CUDA 中,我们称之为网格)。这反过来决定了您在该程序中使用的get_global_id()

      如果您将所有工作组维度设置为空。也就是说,如果我理解正确,您的意思是 1x1 工作组?这将导致大量的工作组,并且流式多处理器 (SM) 只能支持有限数量的工作组(Testla 和 Fermi 中的每个 SM 最多可以支持 8 个工作组)。

      希望对您有所帮助。

      【讨论】:

      • 这个答案是完全错误的。本地大小根本不影响全局 id。 OpenCL 不像 CUDA。此外,将 local 设置为 null 并不意味着 1x1 工作组。它将让驱动程序决定,并且可能会决定最大的一个(除非驱动程序发现没有足够的内存用于这么大的组)[见另一个答案]。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-04
      • 2016-09-03
      • 1970-01-01
      • 2011-03-15
      • 2017-07-23
      • 2023-03-28
      • 1970-01-01
      相关资源
      最近更新 更多