2016-11-08 4 views
1

У меня есть случай, когда после enqueuer ядро ​​получается событие и задается обратный вызов для профилирования. Например:clSetEventCallback, должно ли событие быть сохранено явно?

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 был выделен слишком быстро и был освобожден до вызова callback, но не может его подтвердить.

Итак, мой вопрос заключается в том, должно ли событие быть сохранено явно, прежде чем покинуть область? Или могут быть другие причины?

+0

В качестве побочного комментария: вы должны установить обратный вызов перед использованием события в вызове NDRangeKernel. Потому что ядро ​​может завершить до того, как будет установлен обратный вызов. – DarkZeros

+0

перед входом NDRangeKernel вызывает событие еще недействительным, как установить обратный вызов там? –

ответ

0

Я вычисляю это, перед тем как установить обратный вызов, вызовите clRetainEvent(), и в конце EventCallback вызовите clReleaseEvent(), чтобы событие было действительным до конца обратного вызова. Без выпуска в конце, отладчик сообщит об этом как утечку памяти.

Смежные вопросы