我为OpenCL推出了飞思卡尔i.MX6.Q平台,我得到了有趣的结果,我无法完全解释。我的算法是通过执行4个内核完成的,最后一个是我在这里有趣的一个:经典的图像差异。
我测试了两个版本,一个矢量化版本和一个经典版本(没有矢量化)。起初我对并行差异给出的结果感到惊讶:在这个平台上,OpenCL必须只选择要处理的图像包含180kpix以上(在算法中,图像作为缓冲区处理)。
然而,对于两个OpenCL实现,开头都有常量执行时间(大约5ms)(对于小图像)。我检查了一个空核的执行时间,对于任何测试的图像(从32x32到1920x1024),它们在这个平台上总是大约5ms。
我认为空内核的这些时间是OpenCL差异的并行化成本,我想知道这个成本包含什么?
我的内核编译是在工作台外完成的,我不知道哪一步应该花费5ms。它只是GPU正在处理的NDRange解释吗?
如果有人对此有解释,我会接受!!!
巴普蒂斯特
编辑:
我的时间测量和内核启动:
start_time = time_now();
cl_mem_flags mem_device_host;
if (device.getInfo<CL_DEVICE_HOST_UNIFIED_MEMORY>()==CL_TRUE)
mem_device_host = CL_MEM_USE_HOST_PTR;
else
mem_device_host = CL_MEM_COPY_HOST_PTR;
cl_status = kernel.setArg(0, input_image);
oclReturnOnError(cl_status, "Passage de l'argument 0 du kernel 'morph'")
cl_status = kernel.setArg(1, output_image);
oclReturnOnError(cl_status, "Passage de l'argument 1 du kernel 'morph'")
cl_status = kernel.setArg(2, input_SE);
oclReturnOnError(cl_status, "Passage de l'argument 2 du kernel 'morph'")
cl::Event eventMorph;
cl_status = commandQueue.enqueueNDRangeKernel(kernel,
cl::NullRange,
global_range,
local_range
NULL , &eventMorph);
oclReturnOnError(cl_status, "Ajout du kernel 'morph' à la queue de commande")
cl_status = eventMorph.wait();
oclReturnOnError(cl_status, "Attende d'exécution du kernel 'morph'")
end_time = time_now();
答案 0 :(得分:2)
您的问题主要在于如何确保内核执行。使用OS time_now()会降低分辨率,而不是测试OpenCL性能的方法。
此外,主机慢慢参与GPU工作负载。因此,如果您排队,请不要强制执行(使用clFlush()
)然后被动地等待完成,结果是感知性能非常差。由于您必须等待所有队列和提交,因此您将在通话和实际执行之间看到很多开销。
运行+等待模型对示例和演示有效,但不应用于实际系统或性能测量。
衡量效果的正确方法是使用event
。您可以使用cl::Event.getProfilingInfo<CL_PROFILING_COMMAND_START>()
和cl::Event.getProfilingInfo<CL_PROFILING_COMMAND_END>()
来衡量内核的开始和结束时间。
运行系统的正确方法是,只在需要提取数据时强制执行阻止调用(通常在EnqueueReadBuffer()
)。这样,如果你对一系列内核进行排队,它们将一个接一个地运行,它们之间几乎没有空闲时间。