Как профилировать последовательно запущенные несколько ядер OpenCL одним clFinish?
У меня есть несколько ядер, и они запускаются последовательно следующим образом:
clEnqueueNDRangeKernel(..., kernel1, ...);
clEnqueueNDRangeKernel(..., kernel2, ...);
clEnqueueNDRangeKernel(..., kernel3, ...);
и несколько ядер совместно используют один глобальный буфер.
Теперь я профилирую каждое выполнение ядра и суммирую их для подсчета общего времени выполнения, добавляя блок кода после clEnqueueNDRangeKernel:
clFinish(cmdQueue);
status = clGetEventProfilingInfo(...,&starttime,...);
clGetEventProfilingInfo(...,&endtime,...);
time_spent = endtime - starttime;
У меня такой вопрос: как профилировать все три ядра одним clFinish? (например, добавление одного clFinish () после последнего запуска ядра).
Да, я даю каждому clEnqueueNDRangeKernel различное время и получаю большое отрицательное число. Подробная информация:
clEnqueueNDRangeKernel(cmdQueue,...,&timing_event1);
clFinish(cmdQueue);
clGetEventProfilingInfo(timing_event1,CL_PROFILING_COMMAND_START,sizeof(cl_ulong),&starttime1,NULL);
clGetEventProfilingInfo(timing_event1,CL_PROFILING_COMMAND_END,sizeof(cl_ulong),&endtime1,NULL);
time_spent1 = endtime1 - starttime1;
clEnqueueNDRangeKernel(cmdQueue,...,&timing_event2);
clFinish(cmdQueue);
clGetEventProfilingInfo(timing_event2,CL_PROFILING_COMMAND_START,sizeof(cl_ulong),&starttime2,NULL);
clGetEventProfilingInfo(timing_event2,CL_PROFILING_COMMAND_END,sizeof(cl_ulong),&endtime2,NULL);
time_spent2 = endtime2 - starttime2;
clEnqueueNDRangeKernel(cmdQueue,...,&timing_event3);
clFinish(cmdQueue);
clGetEventProfilingInfo(timing_event3,CL_PROFILING_COMMAND_START,sizeof(cl_ulong),&starttime3,NULL);
clGetEventProfilingInfo(timing_event3,CL_PROFILING_COMMAND_END,sizeof(cl_ulong),&endtime3,NULL);
time_spent3 = endtime3 - starttime3;
time_spent_all_0 = time_spent1 + time_spent2 + time_spent3;
time_spent_all_1 = endtime3 - starttime1;
Если у меня есть все clFinish, все значения профилирования являются разумными, но time_spent_all_1 примерно в 2 раза больше time_spent_all_0. Если я удаляю все clFinish, кроме последнего clFinish, все значения профилирования недопустимы.
Благодаря Эрику Бейнвиллю, я получил желаемый результат: профилирование нескольких clEnqueueNDRangeKernel одним clFinish. Ниже приведен окончательный код, который я использую:
clEnqueueNDRangeKernel(cmdQueue,...,&timing_event1);
clEnqueueNDRangeKernel(cmdQueue,...,&timing_event2);
clEnqueueNDRangeKernel(cmdQueue,...,&timing_event3);
clFinish(cmdQueue);
clGetEventProfilingInfo(timing_event1,CL_PROFILING_COMMAND_START,sizeof(cl_ulong),&starttime,NULL);
clGetEventProfilingInfo(timing_event3,CL_PROFILING_COMMAND_END,sizeof(cl_ulong),&endtime,NULL);
time_spent = endtime - starttime;