float4 - multiply-add - 性能提示OpenCL

时间:2016-07-03 03:27:46

标签: c++ optimization parallel-processing opencl gpu

我正在处理图像处理应用程序,仅限灰度图像 - GPU占用率受每个工作组向量寄存器增加数量和每个工作组本地内存的限制。

read_imagef()函数返回 float4 ,但我的应用程序仅使用 float4的第一个三个组件 - 所以每次计算都有额外的浮点运算 (因此会增加执行时间)。

尽管如此 - 内核在 float4

上也会执行许多 Multiply Add 操作

如何优化这个内核,以便它使用更少的向量寄存器,如果有提示技巧来增加 MAD 操作速度(知道我已经尝试过硬件支持的功能和表现下降了。)

3 个答案:

答案 0 :(得分:2)

如果您只使用灰度图像,则可以实现自己的'read_imagef()',它只读取图像的一个通道,因此您处理的所有内容都是float

由于您的数据可能会在内存中交错为RGBRGB...。仅加载R频道可能与加载所有频道的时间相同。它是结构情况的数组。你可以在这里找到更多细节。

Structure of Arrays vs Array of Structures in cuda

根据数据布局,您可以加载float4 / float3,从中提取一个float频道,然后对提取的float进行计算。

  

内核在float4

上执行许多Multiply Add操作

我不明白为什么你的内核必须在float4上做那些操作。也许你想展示一些代码来证明这一点。

答案 1 :(得分:1)

如果它返回float4并且如果它在与float3相同的内部存储器操作数内执行,那么它将是相同的延迟。疯狂操作的延迟比内存操作短得多。

据我所知,没有float3硬件,所以如果它是标量微架构(例如新的gpu),你可以逐个计算3个元素。如果它是vliw-4那么它将同时使用第四个元素,它将具有相同的速度。

答案 2 :(得分:0)

这里很难具体,因为它取决于它是什么硬件以及你对图像内容做了什么 - 你可能最好将图像处理为字节的普通缓冲区(你自己转换为浮点数) ,但这有可能增加更多的CL代码,并减少GPU中为您进行转换的纹理单元的使用,假设有硬件为此)。

另一种选择是进行四次readimage_f次调用,并将值“合并”为一个float4,进行数学计算,然后拆分结果。

不幸的是,尽管OpenCL是“可移植的”,但它并非“具有已知性能的可移植性”,因此在一个OpenCL实现中运行良好,在另一个OpenCL实现中可能无效,并且调整/调整算法的性能需要很好地理解架构作为一个整体。