Поделиться через


Профилирование приложений DirectX

В этом руководстве показано, как измерять некоторые из наиболее важных измерений времени производительности для приложения DirectX с помощью XPerf и средств GPUView GPUView, которые входят в состав набора средств производительности Windows. Это не комплексное руководство по пониманию инструментов, а их конкретное применимость для анализа производительности приложений DirectX. Хотя большинство описанных здесь методов относятся ко всем приложениям DirectX, это наиболее важно для приложений, использующих цепочки буферов, а не для приложений DirectX, созданных на основе XAML, использующих анимации SIS/VSIS и XAML. Мы рассмотрим ключевые измерения времени производительности, как получить и установить инструменты и средства, делать трассировки измерений производительности, а затем анализировать их, чтобы определить узкие места в приложении.

О средствах

XPerf

XPerf — это набор инструментов анализа производительности, созданных на основе трассировки событий для Windows (ETW), предназначенных для измерения и анализа подробной производительности и использования ресурсов систем и приложений. Начиная с Windows 8 этот инструмент командной строки имеет графический пользовательский интерфейс и называется средство записи производительности Windows (WPR) и Анализатор производительности Windows (WPA). Дополнительные сведения об этих средствах можно найти на веб-странице набора средств оптимизации производительности Windows (WPT): Набор средств оптимизации производительности Windows.

EtW собирает запрошенные события ядра и сохраняет их в файл, называемый файлом журнала трассировки событий (ETL). Эти события ядра предоставляют обширную информацию о характеристиках приложения и системы при запуске приложения. Данные собираются путем включения отслеживания трассировки, выполнения сценария приложения для анализа и остановки записи, после чего данные сохраняются в файле ETL. Затем можно проанализировать файл на одном или другом компьютере с помощью средства командной строки xperf.exe или средства визуального анализа трассировки xperfview.exe.

GPUView

GPUView — это средство разработки для определения производительности графического модуля обработки (GPU) и ЦП. Он рассматривает производительность касательно обработки буфера прямого доступа к памяти (DMA) и всех других видеопроцессов на видеоаппаратуре.

Для приложений DirectX, которые сильно зависят от GPU, GPUView является мощным инструментом для понимания связи между работой на ЦП и GPU. Дополнительные сведения о GPUViewсм. в Использование GPUView.

Как и XPerf, трассировка ETW сначала выполняется путем запуска службы трассировки, выполнения сценария для требующего анализа приложения, остановки службы и сохранения сведений в файле ETL. GPUView представляет данные, присутствующих в файле ETL в графическом формате.

После установки средства GPUView мы рекомендуем прочитать раздел "GPUView"Основной дисплей" в меню "GPUView справки". Он содержит полезные сведения о интерпретации пользовательского интерфейса GPUView.

Установка средств

Оба XPerf и GPUView включены в набор средств производительности Windows (WPT).

XPerf поставляется в составе пакета SDK для Windows. Скачать Windows SDK.

GPUView доступен в комплекте средств для оценки и развертывания Windows (Windows ADK). Скачать Windows ADK.

После установки необходимо добавить каталоги, содержащие XPerf и GPUView в системную переменную Path.

Нажмите кнопку "Пуск" и введите "Системные переменные". Откроется окно свойств системы. Щелкните "Изменить системные переменные среды". Выберите "Переменные среды" в диалоговом окне "Свойства системы". Переменная Path находится в разделе "Системные переменные". Добавьте каталог, содержащий xperf.exe и GPUView.exe в путь. Эти исполняемые файлы находятся в каталоге "Наборы средств производительности Windows" внутри "Комплекты Windows". Расположение по умолчанию: C:\Program Files (x86)\Windows Kits\10\Windows Performance Toolkit.

Измерения времени производительности

Большинство приложений предполагает плавную работу и отзывчивость на действия пользователей. Однако в зависимости от нужного сценария один аспект производительности может быть более важным, чем другой. Например, для приложения чтения новостей, работающего на сенсорном планшетном компьютере, наиболее важным аспектом является просмотр одной статьи за раз и сдвиг/масштабирование или прокрутка одной или другой статьи. В этом сценарии возможность отрисовки всего содержимого каждого кадра не требуется. Однако возможность прокручивать статью плавно на сенсорном жесте крайне важна.

В другой ситуации игра или приложение для рендеринга видео, которое использует множество анимаций, будет иметь сбои, если кадры выпадают. В этом случае возможность представления содержимого на экране без взаимодействия с пользовательским вводом крайне важна.

Чтобы понять, какая часть приложения проблематична, первым шагом является выбор наиболее важных сценариев. Как только основные аспекты приложения будут понятны и как они будут выполняться, поиск проблем с помощью инструментов становится проще.

Ниже приведены некоторые из наиболее распространенных метрик времени производительности.

Время запуска

Время, измеряемое от запуска процесса до первого отображения на экране. Это измерение более полезно, когда система разогрета, что означает, что измерение выполняется после того, как приложение было запущено несколько раз.

Время ЦП на кадр

Время, для которого ЦП активно обрабатывает рабочую нагрузку приложения для одного кадра. Если приложение работает гладко, все обработка, необходимая для одного кадра, происходит в пределах одного интервала синхронизации v-sync. При частоте обновления монитора 60Гц это составляет 16 мс на кадр. Если время ЦП на кадр больше 16 мс, может потребоваться оптимизация ЦП для обеспечения бесперебойной работы приложения.

Время GPU на кадр

Время, для которого GPU активно обрабатывает рабочую нагрузку приложения для одного кадра. Приложение привязано к GPU, если время, затраченное на обработку кадра, составляет более 16 мс.

Если удается выяснить, связано ли приложение с ЦП или GPU, это поможет сузить проблемную часть кода.

Получение трассировки измерения производительности

Выполните следующие действия, чтобы выполнить трассировку:

  1. Откройте командное окно от имени администратора.
  2. Закройте приложение, если оно уже запущено.
  3. Измените каталоги на каталог gpuview в папке Набора средств производительности Windows.
  4. Введите "log.cmd", чтобы начать трассировку событий. Этот параметр регистрирует наиболее интересные события. Другие доступные параметры регистрируют различный охват событий. Например, режим "v" или "подробный журнал" фиксирует все события, которые доступны для GPUView.
  5. Запустите пример и проверьте его таким образом, чтобы он охватывал необходимый путь для анализа производительности.
  6. Вернитесь в окна команд и снова введите "log.cmd", чтобы остановить ведение журнала.
  7. Это выводит файл с именем "merged.etl" в папке gpuview. Этот файл можно сохранить в другом расположении и проанализировать его на одном или другом компьютере. Чтобы просмотреть сведения о записи стека, сохраните файл символов (PDB), связанный с приложением.

Измерения

Заметка

Измерения для образца реализации геометрии проводятся на Quad Core компьютере с интегрированной графической картой DirectX11. Измерения зависят от конфигурации компьютера.

 

В этом разделе показано, как измерять время запуска, а также время работы ЦПУ и ГПУ на каждом кадре. Вы можете записать трассировку производительности для одного и того же примера на компьютере и увидеть различия в различных измерениях.

Чтобы проанализировать трассировку в GPUView, откройте файл merged.elt с помощью GPUView.exe.

Время запуска

Время запуска измеряется общим временем запуска приложения, пока содержимое не появится на экране.

Измерение времени запуска лучше всего предпринять, выполнив действия, перечисленные в предыдущем разделе с этими вариантами:

  • Если вы проводите измерения запуска при первом запуске приложения, это называется холодным запуском. Это может отличаться от измерений, сделанных после запуска приложения несколько раз в течение небольшого периода времени. Это называется теплым запуском. В зависимости от количества ресурсов, которые приложение создает во время запуска, может быть большая разница между двумя временами запуска. В зависимости от целей приложения измерение одного или другого может оказаться желательным.
  • При регистрации сведений о производительности завершите работу приложения, как только на экране появится первый кадр.

Вычисление времени запуска с помощью GPUView

  1. В GPUViewпрокрутите вниз до соответствующего процесса, в этом случае GeometryRealization.exe.

    снимок экрана, показывающий пример процессов в GPUView.

  2. Очередь ЦП контекста представляет графическую рабочую нагрузку, загруженную на оборудование, но не обязательно обрабатываемую им. При открытии файла трассировки отображаются все события, зарегистрированные между временем выполнения трассировки. Чтобы вычислить время запуска, выберите область интереса, увеличьте начальную часть первой очереди ЦП контекста (показывающую активность) с помощью Ctrl + Z. Дополнительные сведения о элементах управления GPUView см. в разделе справки GPUView "Сводка элементов управления GPUView". На рисунке ниже показан только процесс GeometryRealization.exe, увеличенный для просмотра первой части очереди контекстного процессора. Цвет очереди ЦП контекста обозначается цветным прямоугольником прямо под очередью, а пакеты данных того же цвета в очереди указывают на задания GPU, поставленные в очередь на оборудование. Пакет узора штриховки в очереди контекста демонстрирует текущий пакет, что означает, что приложение хочет, чтобы оборудование отображало содержимое на экране.

    снимок экрана, на котором показаны примеры очереди Context C P U.

  3. Время старта — это период от момента первого запуска приложения (в данном случае, модуль точки входа в поток пользовательского интерфейса SHCORE.dll) до того момента, когда контекст впервые появляется (помеченного как "хэтч" пакет). На рисунке здесь выделена область интереса.

    Заметка

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

     

    Полная строка состояния не отображается на рисунке ниже, где также отображается истекшее время между выделенными частями. Это время запуска приложения. В этом случае для компьютера, упоминаемого выше, он вышел около 240 мс.

    Снимок экрана, показывающий области интереса, связанные со временем запуска в очереди Context C P U.

Время ЦП и GPU на кадр

Есть несколько вещей, которые следует учитывать при измерении времени работы процессора. Ищите области в трассировке, где вы выполняли сценарий для анализа. Например, в примере реализации геометрии один из сценариев, которые были проанализированы, — это переход между отрисовкой 2048 и 8192 примитивов, все они остаются нереализованными (то есть, геометрия не тесселлируется каждый кадр). Трассировка четко показывает разницу в активности ЦП и GPU до и после перехода в количестве примитивов.

Два сценария анализируются для вычисления времени ЦП и GPU на кадр. Они следующие.

  • Переход от отрисовки 2048 нереализованных примитивов к отрисовке 8192 нереализованных примитивов.
  • Переход от отрисовки 8192 реализованных примитивов к 8192 нереализованным примитивам.

В обоих случаях было отмечено, что частота кадров резко снизилась. Измерение времени ЦП и GPU, связь между двумя, а также несколькими другими шаблонами трассировки может дать полезные сведения о проблемных областях в приложении.

Вычисление времени ЦП и GPU при отрисовке примитивов 2048 нереализовано

  1. Откройте файл трассировки с помощью GPUView.exe.

  2. Прокрутите вниз до процесса GeometryRealization.exe.

  3. Выберите область для вычисления времени ЦП и увеличения масштаба с помощью КЛАВИШ CTRL+Z.

    Снимок экрана, на котором выделена область для вычисления времени Ц П У в «Context CPU Queue».

  4. Отображение сведений о синхронизации v путем переключения между F8. Продолжайте увеличивать масштаб, пока не станет легко четко увидеть данные за одно значение vsync. Синие линии показывают моменты вертикальной синхронизации. Как правило, они происходят каждые 16 мс (60 fps), но если DWM сталкивается с проблемой производительности, он работает медленнее, поэтому они будут возникать каждые 32 мс (30 fps). Чтобы оценить временные показатели, переместитесь от одной синей панели к следующей, а затем посмотрите на число мс, указанное в правом нижнем углу окна GPUView.

    Снимок экрана, показывающий пример времени вертикальной синхронизации.

  5. Чтобы измерить время ЦП на кадр, измеряйте продолжительность времени, затраченного всеми потоками, участвующими в отрисовке. Возможно, имеет смысл сосредоточиться на потоке, который, как ожидается, окажется наиболее важным с точки зрения производительности. Например, в примере реализации геометрии содержимое анимируется и должно отрисовываться на экране каждый кадр, что делает поток пользовательского интерфейса особенно важным. Когда вы определите, какой поток следует посмотреть, измеряйте длину полос в этом потоке. Усреднение нескольких из них дает время процессора на один кадр. На рисунке ниже показано время, затраченное на поток пользовательского интерфейса. Он также показывает, что этот интервал хорошо вписывается между двумя последовательными вертикальными синхронизациями, что означает достижение 60 FPS.

    снимок экрана, показывающий время, необходимое для потока U I.

    Вы также можете проверить, просмотрев очередь обработки кадров для соответствующего интервала времени, в которой показано, что DWM способен воспроизводить каждый кадр.

    скриншот, показывающий пример 'Перевернуть очередь'.

  6. Время GPU можно измерять так же, как и время ЦП. Увеличьте масштаб соответствующей области, как в случае измерения времени ЦП. Измеряйте длину полос в очереди оборудования GPU с тем же цветом, что и цвет очереди ЦП контекста. Если полосы помещаются в последовательных вертикальных синхронизациях, приложение работает плавно с частотой 60 кадров в секунду.

    снимок экрана, на котором показан пример очереди обработки GPU, отображающей сведения о том, что приложение работает со скоростью 60 кадров в секунду

Вычисление времени работы ЦП и GPU при отрисовке 8192 примитивов без полной реализации

  1. Если выполнить те же действия еще раз, трассировка показывает, что вся работа ЦП для одного кадра не укладывается между одной вертикальной синхронизацией и следующей. Это означает, что приложение привязано к ЦП. Поток пользовательского интерфейса насыщает ЦП.

    Пример потока пользовательского интерфейса, загружающего C P U, на снимке экрана.

    Глядя на очередь флэшировки, также ясно, что DWM не может отображать каждый кадр.

    снимок экрана, на котором показан пример, когда D W M не может показать каждый кадр.

  2. Чтобы проанализировать, где расходуется время, откройте трассировку в XPerf. Чтобы проанализировать время запуска в XPerf, сначала найдите интервал времени в GPUView. Наведите указатель мыши слева от интервала и справа и запишите абсолютное время, показанное в нижней части окна GPUView. Затем откройте тот же ETL-файл в XPerf и прокрутите вниз до графика "Выборка ЦП по ЦП", щелкните правой кнопкой и выберите "Выбрать интервал..." Это позволяет ввести интересующий интервал, который был найден при просмотре трассировки GPU.

    скриншот, показывающий 'Выборка C P U по C P U' в 'Анализе производительности Windows'.

  3. Перейдите в меню Trace и убедитесь, что установлен флажок "Загрузить символы". Кроме того, перейдите в раздел "Трассировка" —> настроить пути символов и введите путь к символам приложения. Файл символов содержит сведения об отладке скомпилированного исполняемого файла в отдельной базе данных (PDB). Этот файл обычно называется PDB. Дополнительные сведения о файлах символов см. здесь: файлы символов. Этот файл можно найти в папке "Отладка" каталога приложения.

  4. Чтобы получить разбивку о том, где время тратится в приложении, щелкните правой кнопкой мыши интервал, выбранный на предыдущем шаге, и нажмите кнопку "Сводная таблица". Чтобы получить общие сведения о том, сколько времени тратится в каждой библиотеке DLL, снимите флажок "Stack" в меню "Столбцы". Обратите внимание, что столбец Count здесь показывает, сколько образцов находятся в заданной dll/функции. Поскольку по одному образцу снимается на мс, это число можно использовать в качестве лучшей оценки того, сколько времени тратится в каждой DLL или функции. Выбор опции "Stack" в меню "Столбцы" предоставит общее время, затраченное на выполнение каждой функции в графе вызовов. Это поможет подробнее детализировать проблемные моменты.

  5. Сведения трассировки стека для 2048 нереализованных примитивов показывают, что в процессе реализации геометрии используется 30% времени ЦП. Из этого около 36% времени тратится на геометрическую тесселяцию и обводку.

  6. Сведения трассировки стека для нереализованных примитивов 8192 показывают, что в реализации геометрии тратится около 60% времени ЦП (4 ядра).

    снимок экрана со сведениями трассировки стека для времени C P U.

Вычисление времени ЦП при отрисовке 8192 примитивов

Из анализа профилей понятно, что производительность приложения ограничена ЦП. Чтобы сократить время, затраченное ЦП, геометрии можно создавать один раз и кэшировать. Кэшированное содержимое можно отрисовывать каждый кадр без учета затрат на геометрическую тесселяцию для каждого кадра. При просмотре трассировки в GPUView для реализованной части приложения явно видно, что DWM способно отображать каждый кадр и время использования ЦП значительно сократилось.

снимок экрана, где видно пример трассировки в GPUView, где DWM может отобразить каждый кадр.

В первой части графа показаны реализованные примитивы 8192. Время обработки ЦП на кадр укладывается в два последовательных интервала виртуальной синхронизации. В более поздней части графа это не верно.

Рассматривая XPerf, видно, что ЦП находится в состоянии простоя большую часть времени, с примерно 25% времени процессора, затраченного на приложение для реализации геометрии.

снимок экрана gpuview.

Сводка

Как GPUView, так и XPerf являются мощными средствами для анализа производительности приложений DirectX. В этой статье описано, как использовать эти средства и понять основные показатели производительности и характеристики приложения. Прежде чем разобраться с использованием инструментов, важно сначала понять анализируемое приложение. Начните с поиска ответов на такие вопросы, как то, что приложение пытается достичь? Какие потоки в системе наиболее важны? Какие компромиссы вы готовы сделать? При анализе трассировок производительности сначала рассмотрим очевидные проблемные места. Приложение ограничено процессором или графическим процессором? Может ли приложение представить каждый кадр? Инструменты вместе с пониманием приложения могут дать очень полезную информацию в понимании, поиске и окончательном решении проблем с производительностью.