clSetEventCallback,如果事件被显式保留

clSetEventCallback, should the event be retained explicitly?

本文关键字:保留 事件 如果 clSetEventCallback      更新时间:2023-10-16

我有一个案例,在进入内核队列之后,获得一个事件并设置回调以进行分析。例如:

cl::Event event;
cl::CommandQueue queue(context, devices[0], 0, &err);
queue.enqueueNDRangeKernel(kernel, cl::NullRange, cl::NDRange(4,4), cl::NullRange, NULL, &event);
event.setcallback(CL_COMPLETE, &EventCallback);

其中Callback是检查内核执行时间的函数

void CL_CALLBACK EventCallback(cl_event event, cl_int, void* pUserData)
{
    cl_int err = CL_SUCCESS;
    cl_ulong submitted = 0, end = 0;
    clGetEventProfilingInfo(event, CL_PROFILING_COMMAND_START, sizeof(cl_ulong), &start, NULL);
    clGetEventProfilingInfo(event, CL_PROFILING_COMMAND_END, sizeof(cl_ulong), &end, NULL);
    ...
}

我忽略了这里的返回错误代码检查,但有时clGetEventProfilingInfo()方法返回CL_INVALID_EVENT。如果运行调试并在回调中设置断点,则不会发生这种情况。

我认为这可能是因为cl::Event对象离开作用域太快,在回调调用之前被释放,但无法确认。

所以我的问题是事件应该在离开作用域之前显式保留吗?还是有其他原因?

我弄清楚了,在设置回调之前,调用clRetainEvent(),并在EventCallback结束时调用clReleaseEvent(),因此事件将在回调结束之前有效。如果最后不释放它,调试器将报告它为内存泄漏。