此代码here表示矩阵乘法,代码使用OpenCL编写。三个矩阵(2 in-1out)的大小为1024x1024。
谈到OpenCL实现,执行范围是二维的,因此我们有1024x1024个工作组,每个工作组由 16x16个工作项组成。
问题是,我们为什么要设置每个工作组的大小,因为在内核中我们既不使用本地内存也不使用get_local_id()调用?将工作组维度设置为null会不会更好,以便每个工作组都可以填充输出矩阵的每个单元格?
对我来说,阅读内核代码(在我链接的页面底部),似乎每个工作组都准备好使用16x16工作项,但最后它们仍未使用。我会将本地大小设置为NULL。为什么他们使用16x16,有什么改进?我很困惑。
答案 0 :(得分:2)
在clEnqueueNDRange中设置本地工作大小只是为了告诉OpenCL设备尝试对来自全局工作组的工作项进行分组以利用并行性。如果将此值保留为null,则OpenCL将选择适当的本地工作大小并执行内核。理想情况下,全局工作大小应该可以被本地工作大小整除,并且本地工作大小应该是设备上计算单元数量的整数倍。因此,即使您将本地工作大小设置为null,我猜OpenCL仍将选择适当的值并并行启动计算。 我已经看到了将本地工作大小设为null的情况使得我的代码比实际给出值更快。
P.S。: - 我仍然是OpenCL的新手,请原谅我的任何小错误。
答案 1 :(得分:0)
问题是,我们为什么要设置每个工作组的大小,因为在内核中我们既不使用本地内存也不使用get_local_id()调用?将工作组维度设置为null会不会更好,以便每个工作组都可以填充输出矩阵的每个单元格?
是的,我们没有使用本地内存或get_local_id()
。但是,您的工作组的大小以及您决定启动的工作组数决定了并行执行的整个计算域(在CUDA中我们称之为网格)。这反过来决定了你在这个程序中使用的get_global_id()
。
如果将所有工作组维度设置为null。也就是说,如果我理解正确,你的意思是1x1工作组?这将导致大量工作组,流式多处理器(SM)只能支持有限数量的工作组(Testla和Fermi中的每个SM最多可支持8个工作组)。
希望有所帮助。