定时间隔始终评估为零

主机上的代码如下:

#include clock_t start,finish; start=clock(); ret = clEnqueueNDRangeKernel(.........); finish=clock(); double time = (double)(finish-start)/(double)(CLOCK_PER_SEC); 

为什么结束 – 始终为0? 是因为分辨率低,还是我的定时器代码有问题?

排队内核非常便宜,因为函数调用可以在内核执行之前返回。

您可以将clEnqueueNDRangeKernel生成的事件用于clWaitForEvents,直到实际执行内核为止。

clEnqueueNDRangeKernel仅对内核进行排队以运行。 与大多数人在调试时习惯使用的传统C代码不同,OpenCL不是一个串行进程。 要强制您的代码以串行方式执行,您可以使它们阻塞(如果可用,请参阅clEnqueueWriteBuffer和clEnqueueReadBuffer),或者在使用cl_command_queue的每个OpenCL命令之后抛出clFinish()。 clFinish()强制cl_command_queue中的所有命令完成。

这允许您轻松使用主机定时器。

其他人提到了分析事件,这是分析OpenCL调用的预期方法。

正如其他人已经推断的那样,如果你正在使用一个解除阻塞的clEnqueueNDRangeKernel(你的代码中没有显式),你就不会测量内核执行时间,因为enqueueing函数返回时没有任何保证内核完成执行(甚至启动它) )。 您可以将对profiling事件的引用传递给enqueue方法,然后查询它的开始和结束时间。 使用cpp包装器:

 cl::Event timingEvent; queue_0.enqueueNDRangeKernel(mx_kernel,cl::NullRange,global,local,NULL,&timingEvent); queue_0.finish();//wait for kernel to be executed timingEvent.getProfilingInfo(CL_PROFILING_COMMAND_START,&start_time); timingEvent.getProfilingInfo(CL_PROFILING_COMMAND_END,&end_time); unsigned long elapsed = (unsigned long)(end_time - start_time); 

为此,您必须在对象构造时启用队列中的分析:

 cl::CommandQueue queue_0 = cl::CommandQueue(context, devices[0], CL_QUEUE_PROFILING_ENABLE);