clSetEventCallback,是否应该显式保留事件?
clSetEventCallback, should the event be retained explicitly?
我有一个案例,在对内核进行排队后,获得一个事件并设置回调以进行分析。例如:
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);
...
}
我忽略了这里的return错误代码检查,但有时clGetEventProfilingInfo()方法returnCL_INVALID_EVENT。如果 运行 调试并在回调中放置断点,则不会发生这种情况。
我认为这可能是因为 cl::Event 对象离开作用域太快,并且在调用回调之前被释放,但无法确认。
所以我的问题是在离开范围之前是否应该显式保留事件?或者可能有其他原因?
我想通了,在设置callback之前调用clRetainEvent(),在EventCallback结束的时候调用clReleaseEvent(),这样event一直有效到callback结束。最后不释放,调试器会报内存泄漏
我有一个案例,在对内核进行排队后,获得一个事件并设置回调以进行分析。例如:
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);
...
}
我忽略了这里的return错误代码检查,但有时clGetEventProfilingInfo()方法returnCL_INVALID_EVENT。如果 运行 调试并在回调中放置断点,则不会发生这种情况。
我认为这可能是因为 cl::Event 对象离开作用域太快,并且在调用回调之前被释放,但无法确认。
所以我的问题是在离开范围之前是否应该显式保留事件?或者可能有其他原因?
我想通了,在设置callback之前调用clRetainEvent(),在EventCallback结束的时候调用clReleaseEvent(),这样event一直有效到callback结束。最后不释放,调试器会报内存泄漏