我有两个输入图像,我从Host传递给内核。 我的图像尺寸为370x427。
我想让自己熟悉本地内存,所以我也将本地图像传递给内核,并尝试将全局图像复制到本地。
我将我的图像作为一维数组发送。当我尝试显示结果时它不起作用。我的全局工作量为{width*height}
我传递null
为本地大小clEnqueueNDRangeKernel
假设opencl会为本地记忆选择合适的大小。
以下是我的内核代码。
请有人给我一个提示。
__kernel void computeSSD(__global unsigned char *imgL,__global unsigned char *imgR,__global unsigned char *result,__global unsigned char *diff,int width,int MAX_DISP,int WIN_SIZE,__local unsigned char *localLeft,__local unsigned char *localRight )
{
int xCord=get_global_id(0);
int yCord=get_local_id(0);
// copy both images to local memory
localRight[yCord]= imgR[yCord];
localLeft[yCord] = imgL[yCord];
barrier(CLK_LOCAL_MEM_FENCE);
// do operation on local images
result[xCord]=localRight[yCord];
//
}
答案 0 :(得分:0)
如果您使用3x3过滤器过滤图像。每个工作组都需要工作组像素+1边距。
所以你的内核可以是:
__kernel filter(...){
int x_start = get_group_id(0)*get_local_size(0)-1;
int y_start = get_group_id(1)*get_local_size(1)-1;
int x_end = (get_group_id(0)+1)*get_local_size(0)+1;
int y_end = (get_group_id(1)+1)*get_local_size(1)+1;
__local mytype l[18][18]; //just an example for work sizes 16x16!
//Fetch
//Normally a direct operation per work item is preferred, since it is simpler and the driver will pack all the memory accesses together.
//So just follow coalesced access
//Using CL async workgroup copy has a complex sintax
for(int j=y_start+get_local_id(1); j<y_end; j+=get_local_size(1) ){
for(int i=x_start+get_local_id(0); i<x_end; i+=get_local_size(0) ){
l[j-y_start][i-x_start] = global[j][i];
}
}
barrier(CLK_GLOBAL_MEM);
//Use the memory for your filtering! (remember to substract y_start & x_start from your original indexes)
//....
}
本地内存不是“是的,让我们全部复制到本地,然后使用它,这样会更快”。它只是复制组所需的区域,并在本地重用这些读取,因此避免了大量的全局读取(即:3x3过滤器,8次全局冗余读取,将内存需求减少到1/9)。
此外,如果您没有真正重复使用工作项之间的读取,本地内存可能会更慢。如果每个项目只读取和写入一个内存位置,本地内存将使内核变慢,而不是更快。