2012-04-03 58 views
0

我已经开始学习openCL编程。作为开始,我正在考虑为以下三次多项式编写优化代码: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. 与500×500的螺纹实现一个内核,该矩阵的一个 元件上每个操作。
  2. 实现一个包含500个线程的内核,每个线程在500个元素上运行,即每个线程在一行上运行。

此外,阵列B1,B2,B3是恒定的阵列。我读到恒定数组可以移动到设备上,并保存在设备内存本地。如果有其他优化可能,请分享。

预先感谢

sravan

回答

0

这里有一些建议:

  1. 对齐矩阵的优选工作组大小的大小 的设备(通常64项效果最好对于大多数设备,但是您可以使用CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLEclGetKernelWorkGroupInfo中查询该值。
  2. 为每个工作项目计算多个元素以减少开销 - 尽管每个工作项目500个元素并不理想,因为 1)它不必要地粗糙化,并且2)它将您限制为只有 500工作-items。
  3. 在内核中,展开迭代元素的循环,在一次迭代中至少执行4个元素。
  4. 你一定要保持设备上的b1,b2和b3阵列。通常,尽可能在设备上保存。

要了解所有优化的完整列表,请阅读OpenCL设备供应商针对您正在使用的设备的优化指南。

0

你一定想用你的算法进行计算绑定,而不是记忆绑定。这里有很多计算要做,所以这不应该是一个问题。我已经回答了关于高效内存访问模式的其他一些问题。 #1#2

我发现,您的建议#2的效果最好 - 即:有一个工作组计算一次一整行的结果。我通过使用更少的组来扩展这个想法,并在工作完成时让他们继续前进到其他行。因为你有足够的工作要做,所以在该行工作结束时为该组使用屏障不会导致性能明显下降。如果您的内存按照行[i * w + 500] ===行[(i + 1)* w]的顺序排列,您可以让工作组一次性关闭两行,并避免一点点停机时间。

我认为500行足够大可以使计算单元保持饱和状态,而不必一次做两行。在我的平台上,CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE是64;如果将64,128或256 id用作工作组大小,则该行上最后一次迭代只有12个工作项空闲。目标是尽可能使用最小的工作组,而不受内存限制(以及首选工作组大小的倍数)。

500个工作组可能太多了。设备上的多个计算单元(我喜欢使用1)将运行良好(请参阅:CL_DEVICE_MAX_COMPUTE_UNITS)。如果您的组数太多,他们将等待安排,或者将被换入/移出设备的内核/寄存器。

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

+0

在我的情况下,条件行[i * w + 500] === row [(i + 1)* w]保持不错。虽然我需要编码和时间的代码。感谢这个建议。 目前我正在尝试在12核心的intel xeon上优化此代码。分析我收集的大小为256x828的数据的性能。我将globalRange设置为256,localRange设置为4,将工作组的数量设置为64.性能已经提高了很多。尽管其他场景我还没有尝试。 我读到,浮动的矢量化可以提高性能方面的很多。你能指出一些关于这方面的好链接吗? 谢谢 – Sravan 2012-04-04 13:26:21