openCL中数学函数的优化

时间:2012-04-03 08:28:03

标签: optimization opencl mathematical-optimization

我已经开始学习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的矩阵。以下是我想实现这个算法的选项:

  1. 使用500x500线程实现内核,每个线程在一个上运行 矩阵的元素。
  2. 实现一个包含500个线程的内核,每个线程在500个元素上运行,即每个线程在一行上运行。
  3. 此外,阵列b1,b2,b3是常数阵列。我读到可以将常量数组移动到设备并将其保存在设备内存本地。如果有任何其他可能的优化,请分享。

    提前致谢

    sravan

2 个答案:

答案 0 :(得分:0)

以下是一些建议:

  1. 将矩阵的大小与首选工作组大小对齐 该设备(通常64个项目最适合大多数设备,但你 可以使用CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE中的clGetKernelWorkGroupInfo来查询值。
  2. 计算每个工作项的多个元素,以减少开销 - 尽管每个工作项500个元素并不理想,因为 1)它是不必要的粗粒度,2)它仅限于你 500个工作项目。
  3. 在内核中,展开循环遍历元素的循环,在一次迭代中至少执行4个元素。
  4. 您应该在设备上保留b1,b2和b3阵列。通常,尽可能多地保留在设备上。
  5. 有关所有可能优化的完整列表,您应该从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)。如果您有太多组,他们将等待安排,或者将被插入/拔出设备的核心/寄存器。

如果您有足够的内存,您肯定希望将常量数据存储在设备上。即使将输出写入本地存储器并在行计算结束时将其复制到全局也可以提高性能。