首页 文章

OpenCL:如何加速过程映像的fps

提问于
浏览
0

我已经开始第一次使用OpenCL了,我正试图在这个站点进行sobel边缘检测这个例子http://www.karlosp.net/blog/2012/05/03/opencl-opencv-sobel-edge-detector/但是当运行时,kernal的gpu数量fps小于15且gpu利用率小于5%可以像openmp那样为gpu运行所有线程,使得利用率降低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));

}

1 回答

  • 0

    您链接的代码有一些低效率(没有特定的顺序):

    • 在循环内的每个OpenCL调用之后调用clFinish是不必要的 . 首先,clEnqueueWriteBuffer和clEnqueueReadBuffer都使用阻塞设置为CL_TRUE,即在写/读完成之前它们不会返回(阻塞函数调用的定义) .

    • 在将无符号字符图像发送到GPU之前,将其转换为浮动图像 . 这不是必需的,因为GPU能够使用unsigned char并且可以根据需要进行类型转换 . 在CPU上转换为float然后发送到GPU会导致发送4x数据量(每个通道每像素4个字节对1个字节) .

    • 你调用cvWaitKey(10),暂停10毫秒等待按键,因此这段代码永远不会超过每秒100帧(次要问题) .

    • RGB到灰度转换可以在GPU上完成,但代价是发送3个无符号字符,因此需要进行权衡,需要进行测试 .

    你的计时方法也存在缺陷 . 您的代码测量加载,处理和显示单个帧所花费的时间 . 处理包括OpenCL和OpenCV组件 . 您应该分别对这些中的每一个进行基准测试,以确定每个测试的时间长度,以便您可以准确确定瓶颈所处的位置 .

    我刚刚想到的是OpenCV从中捕获的相机的帧速率是多少?

相关问题