Platform Analyzer: анализ правильно и неправильно работающих приложений

Моя жена недавно купила довольно толстую и дорогую книгу. Моя жена — врач, специалист по ультразвуковой диагностике детей, она покупает немало книг, но эта книга меня, прямо скажем, озадачила.  Книга называлась «Ультразвуковая анатомия здорового ребенка».  Какой смысл врачу покупать книгу, которая посвящена только здоровым детям?  Я задал этот вопрос жене, и ее ответ был прост: для диагностики у детей любого заболевания, даже если оно еще не выявлено, необходимо знать, как должен работать организм здорового ребенка. 

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

Тук-тук-тук.

Врач говорит: «Войдите!»

В кабинет заходит наш пациент — игра WarriorWave*, где ваша рука прокладывает путь, по которому должны пройти воины. Играть в нее очень интересно и необычно. В игре используется технология Intel ® RealSense. 

Но в процессе игры что-то было не так.  Что-то, чего не ощущалось в других играх на основе технологии Intel ® RealSense™.  Проблема может быть вызвана разными причинами, но что не так в этом случае?  

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

Используя средство Platform Analyzer в составе Intel ® Graphics Performance Analyzer (Intel ® GPA) мы получаем временное представление нагрузки на ЦП, времени создания каждого кадра, кадровой скорости и вызовов отрисовки:

Давайте посмотрим.

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

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

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

Но в нашем случае явно наблюдаются регулярные скачки. Они происходят примерно 4 раза в секунду.  Давайте изучим проблему подробнее, увеличив один из таких скачков, и посмотрим, что при этом происходит в потоках:

Мы видим, что рабочий поток 2780 тратит большую часть времени на синхронизацию. Этот поток практически ничего не делает, только дожидается следующего кадра из Intel ® RealSense™ SDK:

При этом мы видим, что отрисовка происходит в другом рабочем потоке. Если прокрутить вниз, мы найдем поток 2372.

Вместо того, чтобы «активно» ждать следующего кадра от Intel RealSense SDK, игра могла бы делать что-нибудь полезное. Отрисовку и ожидание Intel ® RealSense™ SDK можно было бы поместить в один рабочий поток вместо двух, что упростило бы обмен данными между потоками.

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

Вот пример правильно устроенной игры, в которой работа Intel ® RealSense™ SDK и вызовы DirectX* находятся в одном и том же потоке. 

Специалисты по RealSense™ заявляют, что нет смысла ждать кадры из Intel ® RealSense™ SDK. От этого они не будут появляться быстрее. 

При этом мы видим, что основная проблема находится в верхней части временной шкалы.

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

Теперь перейдем к конвейеру и попробуем разобраться, как идет выполнение кода.  Посмотрите на количество пакетов в Engine 0: конвейер заполнен до краев, но очередь выполнения почти пуста.

Человеческий мозг может обрабатывать до 10–12 изображений в секунду по отдельности. Это поясняет, почему при съемке самых первых кинофильмов пленка протягивалась со скоростью 16 кадров в секунду: это средний порог, после которого большинство людей перестают воспринимать картинку на экране как отдельные изображения и начинают видеть фильм.

Снова посмотрим на профиль правильно работающей игры: 

Обратите внимание, что кадры ГП следуют за кадрами ЦП с небольшим сдвигом. Для каждого кадра ЦП есть соответствующий кадр ГП, выполнение которого начинается после небольшой задержки.

Давайте попробуем понять, почему в нашей игре это не так.

Сначала рассмотрим вызовы DirectX*. Выделенный вызов со всплывающей подсказкой — это наш вызов Present, отправляющий готовый кадр в ГП. На приведенном выше снимке экрана видно, что он создает пакет Present в конвейере ГП (помеченный крестиками).  На отметке 2215 мс он переместился ближе к выполнению, перескочив через три позиции, но на отметке 2231 мс он просто исчез, не завершив выполнение.

Если рассмотреть все вызовы Present в трассировке, окажется, что ни один из них не достиг успешного выполнения.

Вопрос: каким же образом изображение игры вообще появляется на экране, если все вызовы DirectX* Present пропадают?! Хорошо, что у нас есть удобные инструменты, позволяющие получить ответ на этот вопрос. Давайте посмотрим.

Видите нечто любопытное внутри серого овала? Мы видим, что этот пакет, возникший вне всякой связи с какими-либо вызовами DirectX* в нашем коде, все же добирается до выполнения, быстро и без видимого порядка. Минутку, постойте!

Давайте поподробнее изучим наш пакет. 

А теперь — пакет, который все-таки был выполнен. 

Ага! Он появился из ВНЕШНЕГО потока. Что это может означать? Внешние потоки — это потоки, не принадлежащие к игре.

Итак, наши собственные пакеты пропадают, но зато какой-то внешний поток выводит на экран нашу игру? Как это вообще возможно? Может быть, наша программа Platform Analyzer выдает какую-то чепуху?

Нет, на изображении все верно. А объясняется весь этот цирк следующим образом: в системах Windows* (начиная с Windows Vista*) существует программа под названием «диспетчер окон рабочего стола» (DWM), которая и отвечает за фактический вывод изображения на экран. Это пакеты DWM выполнялись быстро и вне очереди, с высоким приоритетом.  А наши пакеты вовсе не пропадали: диспетчер окон рабочего стола перехватывал их для создания итогового изображения.

Но почему диспетчер окон рабочего стола вмешался в работу полноэкранной игры? Подумав, я понял, что ответ прост: к моему компьютеру подключено два монитора. Достаточно было отключить второй монитор из схемы, и все встало на свои места: игра WarriorWave заработала точно так же, как все приличные игры: нормальная кадровая скорость ГП, никаких скачков, никаких пакетов DWM.

Пациент будет жить! Хорошая новость!

Но ведь другие игры вполне хорошо работали и в конфигурации с двумя мониторами, не так ли?

Чтобы изучить проблему подробнее, нужен другой инструмент. Intel ® GPA Platform Analyzer позволяет отслеживать работу ЦП и ГП по времени, но не дает возможности подробно изучать каждый кадр.

Следует более внимательно рассмотреть код создания Direct3D* Device. Для этого можно использовать Intel ® GPA Frame Analyzer для DirectX*, но это уже материал для другой статьи.

Итак, подведем итоги.

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

Заключение: Intel ® GPA Platform Analyzer — очень полезный инструмент для анализа проблем на начальном этапе. Изучите его и используйте его.

Об авторе

Александр Рауд (Alexander Raud) работает в команде Intel ® Graphics Performance Analyzers в России, ранее он работал над программой VTune Amplifier. У Александра двойное гражданство России и Евросоюза, он говорит по-русски, по-английски и немного по-французски, а также изучает испанский язык.  Александр женат, у него двое детей, но, несмотря на это, он находит время, чтобы профессионально играть прогрессивный металл в составе рок-группы и руководить международной миссионерской организацией церкви «Дом Божий».

Дополнительные сведения об оптимизации компиляторов см. в нашем уведомлении об оптимизации.

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