OpenCL内核的定时执行

Timing execution of OpenCL kernels

本文关键字:执行 定时 内核 OpenCL      更新时间:2023-10-16

这是OpenCL内核执行时间的正确计时方式吗?我非常喜欢使用c++包装器(不幸的是,它没有太多计时示例)。

cl::CommandQueue queue(context, device, CL_QUEUE_PROFILING_ENABLE, &err);
checkErr(err, "Cannot create the command queue");
/* Warm-up */
for (unsigned i = 0; i < NUMBER_OF_ITERATIONS; ++i)
{
    err = queue.enqueueNDRangeKernel(kernel, cl::NullRange, cl::NDRange(512), cl::NullRange, NULL, NULL);
    checkErr(err, "Cannot enqueue the kernel");
}
queue.finish();
/* Time kernels */
cl::Event start, stop;
queue.enqueueMarker(&start);
for (unsigned i = 0; i < NUMBER_OF_ITERATIONS; ++i)
{
    err = queue.enqueueNDRangeKernel(kernel, cl::NullRange, cl::NDRange(512), cl::NullRange, NULL, NULL);
    checkErr(err, "Cannot enqueue the kernel");
}
queue.enqueueMarker(&stop);
stop.wait();
cl_ulong time_start, time_end;
double total_time;
start.getProfilingInfo(CL_PROFILING_COMMAND_END, &time_start);
stop.getProfilingInfo(CL_PROFILING_COMMAND_START, &time_end);
total_time = time_end - time_start;
/* Results */
cout << "Execution time in milliseconds " << total_time / (float)10e6 / NUMBER_OF_ITERATIONS << endl;

我认为您的方法应该可以正常工作(不是吗?)。或者,如果要对每次调用计时,可以将一个事件传递给enqueueNDRangeKernel,然后在该enqueueNDRangeKernel上调用getProfilingInfo

cl::Event evt;
err = queue.enqueueNDRangeKernel(kernel, cl::NullRange, cl::NDRange(512), cl::NullRange, NULL, &evt);
evt.wait();
elapsed += evt.getProfilingInfo<CL_PROFILING_COMMAND_END>() -
            evt.getProfilingInfo<CL_PROFILING_COMMAND_START>();