我已经开始学习openCL编程了。作为一个开始,我正在寻找为以下三度多项式编写优化代码:
g(x)= b1(x).f(x)+ b2(x)。(f(x))^ 2 + b3(x)。(f(x)))^ 3
上述等式可以简化为:
g(x)= f(x)[b1(x)+ f(x)[b2(x)+ f(x).b3(x)]]
在很大程度上减少了乘法次数。
假设我的f,b1,b2和b3是大小为500x500的矩阵。以下是我想实现这个算法的选项:
此外,阵列b1,b2,b3是常数阵列。我读到可以将常量数组移动到设备并将其保存在设备内存本地。如果有任何其他可能的优化,请分享。
提前致谢
sravan
答案 0 :(得分:0)
以下是一些建议:
CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE
中的clGetKernelWorkGroupInfo
来查询值。有关所有可能优化的完整列表,您应该从OpenCL设备供应商处阅读您正在使用的设备的优化指南。
答案 1 :(得分:0)
您肯定希望与算法绑定计算,而不是受内存限制。这里有很多计算要做,所以这应该不是问题。我已回答了有关高效内存访问模式的其他几个问题。 #1,#2。
我发现你的建议#2效果最好 - 即:让工作组一次计算整行的结果。我通过使用更少的组来扩展这个想法,并在工作完成后让它们移动到其他行。因为你有足够的工作要做,所以在行结束时使用障碍为行不会显着地降低性能。如果您的内存订购时行[i * w + 500] === row [(i + 1)* w],您可以让您的工作组一次压缩两行并避免一点点停机时间
我认为500行是足够大的工作来保持计算单元饱和,而不必一次做两行。在我的平台上,CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE是64;如果64,128或256 id用作工作组大小,则该行的最后一次迭代只有12个工作项空闲。目标是尽可能使用最小的工作组,而不是内存限制(以及首选工作组大小的倍数)。
500个工作组可能太多了。设备上的一些多个(我喜欢使用1个)计算单元将运行良好(请参阅:CL_DEVICE_MAX_COMPUTE_UNITS)。如果您有太多组,他们将等待安排,或者将被插入/拔出设备的核心/寄存器。
如果您有足够的内存,您肯定希望将常量数据存储在设备上。即使将输出写入本地存储器并在行计算结束时将其复制到全局也可以提高性能。