为什么CPU和GPU内存之间的数据交换速度如此之慢?

时间:2015-03-21 06:37:25

标签: opencv arm opencl gpu

这是我第一次在ARM上使用openCL(CPU:Qualcomm Snapdragon MSM8930,GPU:Adreno(TM)305)。

我发现使用openCL非常有效,但CPU和GPU之间的数据交换需要花费太多时间,因为我无法成像。

以下是一个例子:

cv::Mat mat(640,480,CV_8UC3,cv::Scalar(0,0,0));
cv::ocl::oclMat mat_ocl;

//cpu->gpu
mat_ocl.upload(mat);
//gpu->cpu
mat = (cv::Mat)mat_ocl;

这样的小图片,上传选项需要10毫秒,下载选项需要20毫秒!这花了太长时间。

任何人都可以告诉我这种情况是否正常?或者这里出了什么问题?

提前谢谢!

加入:

我的混乱方法是

clock_t start,end;
start=clock();
mat_ocl.upload(mat);
end = clock();
__android_log_print(ANDROID_LOG_INFO,"tag","upload time = %f s",(double)(end-start)/CLOCKS_PER_SEC);

实际上,我并没有完全使用openCL,而是使用openCV中的ocl模块(尽管它说它们是相同的)。在阅读openCV文档时,我发现它只是告诉我们将cv :: Mat转换为cv :: ocl :: oclMat(这是从CPU上传到GPU的数据)来进行GPU计算,但我没有'在ocl模块文件中找到了内存映射方法。

2 个答案:

答案 0 :(得分:2)

好吧,我在openCV doc中找到了一些有用的介绍:

  

在异构设备环境中,可能存在与数据传输相关的成本。例如,当需要将数据从主机存储器(可由CPU访问)移动到设备存储器(可由独立GPU访问)时,就是这种情况。在集成图形芯片的情况下,可能存在性能问题,涉及从集成设备的GPU“部分”访问或CPU“部分”之间的存储器一致性。为了获得最佳性能,在任何一种情况下,建议除了在算法管道的开头和结尾之外,你不会在CPU和离散GPU之间引入数据传输。

因此,似乎解释了CPU和GPU之间数据传输速度如此之慢的原因。但我仍然不知道如何解决这个问题。

答案 1 :(得分:1)

提供准确的测量方法和结果。

根据ARM平台下的OpenCL开发经验(不是Qcom),我可以说你不应该期待大量的读写操作。内存总线通常像64位,加上DDR3并不快。

使用共享内存是有利的 - 去映射/取消映射而不是读/写。

P上。使用cl_event profiling:

测量S.实际操作时间
cl_ulong getTimeNanoSeconds(cl_event event)
{
    cl_ulong start = 0, end = 0;

    cl_int ret = clWaitForEvents(1, &event);
    if (ret != CL_SUCCESS)
        throw(ret);

    ret = clGetEventProfilingInfo(
              event,
              CL_PROFILING_COMMAND_START,
              sizeof(cl_ulong),
              &start,
              NULL);
    if (ret != CL_SUCCESS)
        throw(ret);

    ret = clGetEventProfilingInfo(
              event,
              CL_PROFILING_COMMAND_END,
              sizeof(cl_ulong),
              &end,
              NULL);
    if (ret != CL_SUCCESS)
        throw(ret);

    return (end - start);
}