我第一次开始使用OpenCL,我试图为sobel做这个例子 此站点的边缘检测 http://www.karlosp.net/blog/2012/05/03/opencl-opencv-sobel-edge-detector/ 但是当运行时,核心数为fps的核心小于15和gpu利用率 小于5%如何运行gpu之类的所有线程,如openmp,使利用率低于95%
代码
核心代码
_ kernel void sobel( _global float * A,__ global float * R,uint width,uint height) {
int globalIdx = get_global_id(0);
int globalIdy = get_global_id(1);
int index = width * globalIdy + globalIdx;
float a,b,c,d,e,f,g,h,i;
float sobelX = 0;
float sobelY = 0;
if(index > width && index < (height*width)-width && (index % width-1) > 0 && (index % width-1) < width-1){
a = A[index-1-width] * -1.0f;
b = A[index-0-width] * 0.0f;
c = A[index+1-width] * +1.0f;
d = A[index-1] * -2.0f;
e = A[index-0] * 0.0f;
f = A[index+1] * +2.0f;
g = A[index-1+width] * -1.0f;
h = A[index-0+width] * 0.0f;
i = A[index+1+width] * +1.0f;
sobelX = a+b+c+d+e+f+g+h+i;
a = A[index-1-width] * -1.0f;
b = A[index-0-width] * -2.0f;
c = A[index+1-width] * -1.0f;
d = A[index-1] * 0.0f;
e = A[index-0] * 0.0f;
f = A[index+1] * 0.0f;
g = A[index-1+width] * +1.0f;
h = A[index-0+width] * +2.0f;
i = A[index+1+width] * +1.0f;
sobelY = a+b+c+d+e+f+g+h+i;
}
R[index] = sqrt(pow(sobelX,2) + pow(sobelY,2));
}
答案 0 :(得分:0)
您链接的代码有一些低效率(没有特定的顺序):
在循环内的每个OpenCL调用之后调用clFinish是不必要的。首先,clEnqueueWriteBuffer和clEnqueueReadBuffer都使用阻塞设置为CL_TRUE,即在写/读完成之前它们不会返回(阻塞函数调用的定义)。
在将无符号字符图像发送到GPU之前,将其转换为浮动图像。这不是必需的,因为GPU能够使用unsigned char并且可以根据需要进行类型转换。在CPU上转换为float然后发送到GPU会导致发送4倍的数据量(每个通道每像素4个字节对1个字节)。
你调用cvWaitKey(10),暂停10毫秒等待按键,因此这段代码永远不会超过每秒100帧(小问题)。
RGB到灰度转换可以在GPU上完成,但代价是发送3个无符号字符,因此需要进行权衡,需要进行测试。
您的计时方法也存在缺陷。您的代码测量加载,处理和显示单个帧所花费的时间。处理包括OpenCL和OpenCV组件。您应该分别对这些中的每一个进行基准测试,以确定每个项目需要多长时间,以便您可以准确确定瓶颈所处的位置。
我刚刚想到的是OpenCV从中捕获的相机的帧速率是多少?