我是opencl的新手,现在我正在用opencl优化模板匹配。我用较小的模板做了一些实验,发现我的OpenCL实现比OpenCV的CPU版本更快。但在这种特殊情况下,模板大小非常大(2048x2048),原始图像大小为(3072x3072),OpenCV cpu实现(137秒)远远领先于OpenCL(2000秒)。请建议一些方法来优化下面显示的代码。
void __kernel corrln(global const unsigned char* ref_image, global const
unsigned char* template, global float* corrln )
{
const uint Width = get_global_size(0);
const int2 pos = {get_global_id(0), get_global_id(1)};
float sum = 0;
for(int y = pos.y; y < 2048; y++ )
{
for(int x =pos.x; x < 2048; x++ )
{
const int2 xy = { x, y };
const int2 txy = { x - pos.x, y - pos.y };
sum += ref_image[index(xy, Width)] * template[index(txy,
2048)];
}
}
corrln[index(pos, Width)]= sum;
}
考虑到ref_image
的合理大小小于 2048(例如 1024x1024),并且 ND 大小等于 ref_image
大小,每个 WI(工作项)都在执行不同数量的计算。
WI 与位置 x == 0
尝试以这样一种方式来分割这项任务,使得每个WI将进行一些合理的固定数量的计算。比方说,对于< code>ref_image的第一列,多次启动内核,每次都会向右处理16列并计算
内核可能看起来像这样(仅用于说明!!!):
void __kernel corrln(
global const unsigned char* ref_image,
global const unsigned char* template,
global float* corrln )
{
const uint Width = get_global_size(0);
const int2 pos = {get_global_id(0), get_global_id(1)};
uchar16 ref = vload16(index(xy, Width), ref_image);
uchar16 tpl = vload16(index(xy, Width), template);
float sum = corrln[index(pos, Width)] + dot(ref, tpl);
corrln[index(pos, Width)]= sum;
}