这是我第一次在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模块文件中找到了内存映射方法。
答案 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);
}