Optimization openCL中数学函数的优化

Optimization openCL中数学函数的优化,optimization,opencl,mathematical-optimization,Optimization,Opencl,Mathematical Optimization,我已经开始学习openCL编程。首先,我考虑为以下三次多项式编写优化代码: gx=b1x.fx+b2x.fx^2+b3x.fx^3 上述等式可简化为以下等式: gx=fx[b1x+fx[b2x+fx.b3x]] 这在很大程度上减少了乘法的次数 假设我的f、b1、b2和b3是大小为500x500的矩阵。以下是我想到的实现此算法的选项: 实现一个包含500x500个线程的内核,每个线程在一个线程上运行 矩阵的元素。 实现一个包含500个线程的内核,每个线程在500个元素上运行,即每个线程在一行上运行

我已经开始学习openCL编程。首先,我考虑为以下三次多项式编写优化代码:

gx=b1x.fx+b2x.fx^2+b3x.fx^3

上述等式可简化为以下等式:

gx=fx[b1x+fx[b2x+fx.b3x]]

这在很大程度上减少了乘法的次数

假设我的f、b1、b2和b3是大小为500x500的矩阵。以下是我想到的实现此算法的选项:

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

提前谢谢


斯拉万

以下是一些建议:

将矩阵的大小与首选的工作组大小对齐 该设备通常64项最适合大多数设备,但您 可以使用clGetKernelWorkGroupInfo中的CL\内核\首选\工作\组\大小\倍数查询该值。 每个工作项计算多个元素,以减少开销-尽管每个工作项500个元素并不理想,因为 1它是不必要的粗粒度,2它将您限制为 500个工作项目。 在内核内部,展开迭代元素的循环,在一次迭代中至少执行4个元素。 您一定要在设备上保留b1、b2和b3阵列。通常,在设备上尽可能多地保存。
要获得所有可能的优化的完整列表,您应该阅读OpenCL设备供应商针对您正在使用的设备提供的优化指南

您肯定希望算法与计算绑定,而不是内存绑定。这里有很多计算要做,所以这应该不是问题。我已经回答了几个关于高效内存访问模式的其他问题

我发现你的建议2最有效——即:让一个工作组一次计算整行的结果。我通过使用更少的组来扩展这个想法,并在工作完成后让他们移动到其他行。在行的工作结束时为小组设置障碍不会显著降低绩效,因为您有足够的工作要做。如果您的内存排序为第[i*w+500]行===第[i+1*w]行,您可以让您的工作组一次处理两行,避免一点停机时间

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

500个工作组可能太多了。我喜欢在设备上使用1个计算单元的一些倍数会很好地工作,请参见:CL\u设备\u MAX\u计算单元。如果您有太多的组,它们将等待调度,或者将因在设备的核心/寄存器中进行交换而受到影响


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

在我的情况下,条件行[i*w+500]===行[i+1*w]保持良好。虽然我需要编码并计时。谢谢你的建议。目前,我正在尝试在12核intel xeon上优化此代码。为了分析性能,我获取了大小为256x828的数据。我将globalRange设置为256,localRange设置为4,工作组的数量设置为64。性能有了很大的提高。不过对于其他场景,我还没有尝试。我读到浮点的矢量化可以在性能方面提高很多。你能给我指一些关于这个的好链接吗。谢谢