Parallel processing OpenCL:如何加快处理图像的fps

Parallel processing OpenCL:如何加快处理图像的fps,parallel-processing,opencl,processing,frame-rate,Parallel Processing,Opencl,Processing,Frame Rate,我第一次开始使用OpenCL,我正试图为sobel做这个例子 此站点中的边缘检测 但是当运行内核时,gpu的fps数小于15,gpu的利用率也会降低 小于5%如何为gpu(如openmp)运行所有线程以使利用率低于95% 代码 核码 _内核无效sobel(_全局浮点*A,_全局浮点*R,单位宽度,单位高度) { int globalIdx=get\u global\u id(0); int globalIdy=get\u global\u id(1); int index=width*globa

我第一次开始使用OpenCL,我正试图为sobel做这个例子 此站点中的边缘检测 但是当运行内核时,gpu的fps数小于15,gpu的利用率也会降低 小于5%如何为gpu(如openmp)运行所有线程以使利用率低于95%

代码

核码

_内核无效sobel(_全局浮点*A,_全局浮点*R,单位宽度,单位高度) {

int globalIdx=get\u global\u id(0);
int globalIdy=get\u global\u id(1);
int index=width*globalIdy+globalIdx;
浮点数a、b、c、d、e、f、g、h、i;
float-sobelX=0;
float-sobelY=0;
如果(索引>宽度和索引<(高度*宽度)-宽度和(索引%width-1)>0和(索引%width-1)

}

您链接到的代码有一些低效之处(无特定顺序):

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

  • 将未签名的字符图像转换为浮点图像,然后再发送到GPU。这是不必要的,因为GPU能够处理无符号字符,并且如果需要,可以将类型转换为浮点。在CPU上转换为浮点,然后发送到GPU,会导致发送的数据量增加4倍(每个通道每像素4字节,而不是1字节)

  • 您调用cvWaitKey(10),暂停10毫秒以等待按键,因此此代码不会超过每秒100帧(小问题)

  • RGB到灰度的转换可以在GPU上完成,代价是发送3个未签名字符,因此需要进行测试

你的计时方法也有缺陷。代码测量加载、处理和显示单个帧所需的时间。处理由OpenCL和OpenCV组件组成。您应该分别对其中的每一个进行基准测试,以确定每一个测试需要多长时间,这样您就可以准确地确定瓶颈所在的位置


我刚刚想到的是OpenCV拍摄的相机的帧速率是多少?

您是否在每次迭代中使用clenqueuewrite/read?这会降低性能。如果你只能在gpu上进行同样的计算,那么速度会更快,因为边缘检测的计算量并不大。它主要使用mem访问。如果pci-e优化不够,您可以使用每个线程块的共享mem优化来优化mem访问。当针对非pci-e访问进行优化时,即使使用粒子交互+可变形网格计算,该示例的256x256纹理分辨率也要快很多倍。Cl gl interop是事物的名称。请输入一些密码。谢谢你的回答。你能帮我一些代码吗?我想让gpu像openmp一样100%运行cpu线程我的实际程序从相机或视频中读取帧,在cpu上进行一些处理,然后发送到gpu进行一些处理,我想进行canny边缘检测和hougth变换,然后返回cpu完成处理。sobel检测以15fps的速度运行,分辨率为640*480°??我使用clenqueuewrite/read-to在每个帧后从gpu读写,这是否可以进行实时处理???Pci-e带宽通常为每秒4-5GB。这意味着每秒有10亿个32位浮点。640*480=307200,再乘以每像素4字节(rgba),得到每帧1228800字节,是pci-e带宽的1/4000。您有15FPS,因此它每秒发送的速度可能为16MB,这太少了。但是发送时间使得gpu空闲。即使闲置一毫秒,GPU的使用率也会降低。如果不需要互操作,那么可以执行异步工作。首先,向gpu发送50个待处理帧。启动内核。但同时发送和接收新的数据,同时保持gpu繁忙。然后,您可以让gpu繁忙地处理预加载到gpu内存中的帧。我认为这只是一个现实,你有一个高端gpu,我认为:)你不能得到100%,即使你大量优化它。5%并不意味着GPU以5%的速度运行,而是意味着平均使用率为5%。如果您的代码运行速度快,并且I/O是一个瓶颈(以及CPU查询数据)。你几乎不会超过这个水平。IE:非常繁重的计算任务通常只达到50%,CPU也是瓶颈。谢谢你的回答。我在代码中做了一些更改,但gpu的利用率也低于5%,fps达到20 1-chang cvWaitKey(10)从10毫秒到1毫秒2-remove clFinish在循环内3-RGB到灰色CVT颜色(img,im_gray,CV_RGB2GRAY);如果在循环中仅使用此函数,fps 35 4-在将未签名字符图像发送到GPU之前将其转换为浮点图像?你知道如何优化内核以使用gpu的所有资源吗我想在gpu上并行运行利用率超过5%我看到一些内核使用get_local_size&get_num_Group这个函数能帮助我加快内核运行速度吗如何优化2d图像的内核谢谢从使用共享a.k.a.本地内存中获益,但代码中似乎还有其他瓶颈。你如何衡量GPU的使用情况。如果你是你
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));