繁体   English   中英

定时间隔始终为零

[英]Timed interval always evaluates to zero

主机上的代码如下:

#include<time.h>
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(在代码中未明确显示),那么您就无法衡量内核的执行时间,因为排队函数返回时并不能保证内核已完成执行(甚至启动了)。 )。 您可以将对概要分析事件的引用传递给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);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM