Я создаю пользовательский интерфейс инструмента с моим приложением для профилирования производительности ядер OpenCL, а также интегрирую точки профилирования ЦП. В настоящее время я работаю с этим кодом на Linux с использованием Ubuntu, и я тестирую на своей машине 3 устройства OpenCL: процессор Intel, Intel IGP и Nvidia Quadro.
Я использую этот код std::chrono::high_resolution_clock::now().time_since_epoch().count()
для создания отметки времени на ЦП, и, конечно же, для временных точек профилирования OpenCL они представляют собой 64-битные наносекунды, предоставляемые API событий профилирования OpenCL. Цель созданного мною инструмента - использовать вывод журнала (специально отформатированный и сгенерированный, чтобы не сильно влиять на производительность) из программы и генерировать временную диаграмму для облегчения анализа производительности.
Пока что в моем интерфейсе визуализации Я сделал предположение, что наносекунды единообразны. Я понял теперь, после того как мой визуальный интерфейс заработал и проверил несколько предположений, что это условие более или менее соответствует стандартному отклонению в 0,4 микросекунды для устройства CPU OpenCL (что указывает на то, что устройство CPU может быть реализовано с использованием того же времени счетчик, так как у него нет дрейфа), но не работает для двух устройств GPU! Возможно, это не самая удивительная вещь в мире, но она влияет на основную конструкцию моего инструмента, так что это был непредвиденный риск.
Я предоставлю немного конфет, так как это очень интересно и действительно доказывает мне, что это действительно происходит.
Увеличивается в начале профиля, где у GPU есть соответствующий mapBuffer для поз, происходящих примерно за миллисекунду до того, как CPU его вызовет (невозможно!)
![at the beginning](https://i.stack.imgur.com/VOxgG.png)
Ближе к концу профиля мы видим те же формы, но обратное соотношение, ясно показывая, что секунды графического процессора имеют немного меньшее значение по сравнению с секундами процессора.
![near the end](https://i.stack.imgur.com/97gcQ.png)
Способ, которым эта визуализация в настоящее время работает, как я предполагал, наносекунда графического процессора на самом деле наносекунда процессора, заключается в том, что я фактически вычислял среднее разницы между значениями, данными мне CPU и GPU ... Поскольку я реализовал это изначально, возможно, это указывает на то, что я, по крайней мере, подсознательно ожидал, что возникнет проблема, подобная этой. В любом случае, я установил sh точку синхронизации c в диспетчере ядра, записав метку времени ЦП непосредственно перед вызовом clEnqueueNDRangeKernel
, а затем сравнив это с временем события CL_PROFILING_COMMAND_QUEUED
профиля OpenCL. Эта дельта при дальнейшем осмотре показала дрейф времени:
![console screenshot](https://i.stack.imgur.com/IxMs5.png)
Этот снимок экрана с консоли chrome показывает, что я записываю в журнал массив значений дельты, которые я собрал из эти два устройства GPU; они показывают BigInts, чтобы избежать потери целочисленной точности: в обоих случаях дельты отметок времени, сообщаемые GPU, имеют тенденцию к снижению.
Сравните с числами от CPU:
![cpu console screenshot](https://i.stack.imgur.com/P0tCa.png)
Мои вопросы:
- Каким может быть практический способ решения этой проблемы? В настоящее время я склоняюсь к использованию точек синхронизации c при отправке ядер OpenCL, и эти точки синхронизации c могут использоваться либо для локального кусочного растягивания временных меток профилирования OpenCL, либо для локальной синхронизации c в начале, скажем, отправка ядра, и просто игнорируйте имеющееся у нас несоответствие, предполагая, что оно будет незначительным в течение периода. В частности, неясно, будет ли хорошей идеей максимизировать детализацию путем реализации точки syn c для каждого отдельного события профилирования, которое я хочу использовать.
- Какие могут быть другие системы измерения времени, которые я могу или следует использовать на стороне процессора, чтобы увидеть, возможно, они в конечном итоге будут лучше выравниваться? На данный момент у меня нет особой надежды на это, потому что я могу представить, что время профилирования, предоставляемое мне, фактически генерируется и рассчитывается на самом устройстве GPU. Тогда на колебания будут влиять такие вещи, как динамическое c масштабирование тактовой частоты графического процессора, и не было бы никакой надежды наткнуться на другую лучшую схему хронометража на CPU.