Неоднозначность событий OpenCL

#parallel-processing #opencl #gpu

#параллельная обработка #opencl #графический процессор

Вопрос:

Ссылка на документацию clGetEventProfilingInfo, cl_event полученную из clEnqueueNDRangeKernel, может быть:

  1. CL_PROFILING_COMMAND_QUEUED

когда команда, идентифицированная событием, помещается хостом в очередь команд.

  1. CL_PROFILING_COMMAND_SUBMIT

когда команда, идентифицированная событием, которое было поставлено в очередь, отправляется хостом на устройство, связанное с commandqueue.

  1. CL_PROFILING_COMMAND_START

когда команда, идентифицированная событием, начинает выполнение на устройстве.

  1. CL_PROFILING_COMMAND_END

когда команда, идентифицированная событием, завершила выполнение на устройстве.


Предположим, что визуализация всего профилирования ядра:

 COMMAND_QUEUED -> COMMAND_SUBMIT -> COMMAND_START -> COMMAND_END
  

и соответствующая временная шкала:

 Queueing -> Submitting -> Executing
  

Где:

  • Постановка в очередь = COMMAND_SUBMIT — COMMAND_QUEUED
  • Отправка = COMMAND_START — COMMAND_SUBMIT
  • Выполнение = COMMAND_END — COMMAND_START

Верны ли
вопросы: мои предыдущие уравнения? если да, то в чем реальная разница между постановкой в очередь и отправкой? Другими словами, если я хочу разделить весь процесс на время СВЯЗИ (выгрузки) и время ВЫЧИСЛЕНИЯ (выполнения), каковы будут их уравнения?

Ответ №1:

Ваша интерпретация кажется довольно верной. ОЧЕРЕДЬ возникает, когда вы вызываете API OpenCL (например, clEnqueueNDRangeKernel). ОТПРАВКА — это когда среда выполнения передала работу устройству. НАЧАЛО — это когда началось выполнение, КОНЕЦ — когда выполнение завершено. Между этими четырьмя временами есть три состояния. Первое состояние простаивает на хосте. Второе состояние — бездействие на устройстве. Третье состояние выполняется на устройстве. Если вы хотите объединить первые два в «связь», добавьте их вместе (или используйте COMMAND_START — COMMAND_QUEUED ).

Комментарии:

1. при запуске на процессоре QUEUED = 0, однако SUBMIT не является! почему?

2. Не знаю почему. Похоже на ошибку в реализации.

3. я сомневаюсь, потому что числа различаются на графическом процессоре, отправка занимает больше времени, чем постановка в очередь! какая реализация, эти показания получены из фактического профилирования выполнения!

4. Вы сказали COMMAND_QUEUED, поэтому я подумал, что вы имели в виду, что значение, возвращаемое при запросе CL_PROFILING_COMMAND_QUEUED, равно 0, что было бы ошибкой в реализации (во время выполнения). Если вместо этого вы имеете в виду, что значения из CL_PROFILING_COMMAND_QUEUED и CL_PROFILING_COMMAND_SUBMIT одинаковы, что делает ваше вычисленное значение «очередью» 0, тогда все в порядке. Это просто означает, что среда выполнения не проводила время в этом состоянии и отправлялась при вызове API.

5. Очередь равна 0 в CPU, поскольку очереди нет, когда у вас есть только одна задача в CPU. Однако, если у вас ранее были запущены ядра, очередь не будет равна 0. Графические процессоры разные, поскольку они асинхронны, вы всегда будете получать некоторое время ожидания в очереди.

Ответ №2:

Верны ли мои предыдущие уравнения?

ДА.

Если да, то в чем реальная разница между постановкой в очередь и отправкой? Другими словами, если я хочу разделить весь процесс на время СВЯЗИ (выгрузки) и время ВЫЧИСЛЕНИЯ (выполнения), каковы будут их уравнения?

Постановка в очередь:

  • Потратьте время на ожидание завершения других задач, чтобы начать текущую. Другими словами, ожидание состояния CL_COMPLETE всех зависимых событий или наличие свободных ресурсов в текущей очереди.
  • Примечание: процессоры будут иметь время ожидания 0 при постановке в очередь на неработающее устройство, поскольку они синхронны. В то время как графические процессоры ВСЕГДА будут иметь небольшое время ожидания в очереди в любом случае (из-за асинхронного поведения). Это причина для максимально возможной передачи на устройства с графическим процессором.

Отправка:

  • Время, затраченное на подготовку текущей задачи (компиляция LLVM, перемещение буферов, подготовка ядер устройств и т. Д.), Должно быть небольшим, но не 0.

Если вы ищете формулу, для вычисления накладных расходов текущей задачи допустимы только «Отправка» и «Выполнение». Игнорируйте постановку в очередь, поскольку она не зависит от вашей задачи:

 Active% = Executing/(Executing Submitting)
Overhead% = Submitting/(Executing Submitting)