Engine & platform

Профилирование в Unity 2021 LTS: Что, когда и как

THOMAS KROGH-JACOBSEN / UNITY TECHNOLOGIESProduct Marketing Core Tech
Jun 1, 2022|23 Мин
Профилирование в Unity 2021 LTS: Что, когда и как
Эта веб-страница была переведена с помощью машинного перевода для вашего удобства. Мы не можем гарантировать точность или надежность переведенного контента. Если у вас есть вопросы о точности переведенного контента, обращайтесь к официальной английской версии веб-страницы.

Развитие опыта работы с набором инструментов профилирования Unity - один из самых полезных навыков, которые вы можете добавить в свой набор инструментов для разработки игр. Тщательное профилирование может значительно повысить производительность вашей игры, поэтому мы хотим помочь вам начать с ключевых советов из нашей недавно выпущенной электронной книги " Ultimate guide to profiling Unity games".

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

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

Давайте рассмотрим несколько полезных советов из этой электронной книги.

Когда составлять профиль

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

Инструменты профилирования в конечном итоге помогут вам понять, что происходит "под капотом" вашего проекта Unity. Но не ждите, пока начнут проявляться значительные проблемы с производительностью, прежде чем копаться в своем наборе инструментов детектива.

Наибольший эффект от профилирования достигается при планировании на ранних этапах жизненного цикла разработки проекта, а не непосредственно перед отправкой игры. Это постоянный, проактивный и итеративный процесс. Благодаря раннему и частому профилированию вы и ваша команда сможете понять и установить "подпись производительности" для проекта. Если, например, производительность упадет, вы сможете легко заметить, когда что-то пошло не так, и быстро устранить проблему.

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

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

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

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

Инструменты в вашем распоряжении

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

Хотя Unity поставляется с рядом бесплатных и мощных инструментов профилирования для анализа и оптимизации вашего кода как в редакторе, так и на аппаратном уровне, существует также несколько отличных собственных инструментов профилирования, разработанных для каждой платформы, например, от Arm, Apple, Sony и Microsoft. Использование комбинации позволяет получить более целостное представление о производительности приложений на всех целевых устройствах.

Полный обзор доступных инструментов можно найти на странице инструментов профилирования здесь.

Инструменты профилирования Unity доступны в редакторе и менеджере пакетов. Каждый инструмент специализируется на профилировании различных частей процесса (целостный рабочий процесс "сумма всех частей"). Ознакомьтесь со следующими профилировщиками, чтобы они стали частью вашего повседневного инструментария:

  • Unity Profiler - это то, с чего вы хотите начать и на что потратите большую часть своего времени. Он измеряет производительность редактора Unity, вашего приложения в режиме Play и подключается к устройству, на котором запущено ваше приложение в режиме разработки. Unity Profiler собирает и отображает данные о производительности вашего приложения, например, сколько процессорного времени используется для выполнения различных задач, от аудио и физики до рендеринга и анимации. Для начала ознакомьтесь с этим курсом по профилированию.
  • Memory Profiler обеспечивает глубокий анализ производительности памяти, чтобы определить, где вы можете уменьшить использование памяти в некоторых частях вашего проекта и редактора. В настоящее время Memory Profiler находится в стадии предварительного просмотра, но ожидается, что он будет проверен в Unity 2022 LTS.
  • Анализатор профиля объединяет и визуализирует данные кадров и маркеров из набора кадров Unity Profiler, чтобы помочь вам изучить их поведение на протяжении многих кадров (в дополнение к однокадровому анализу, уже доступному в Unity Profiler). Он также позволяет сравнить два набора данных профилирования, чтобы определить, как ваши изменения влияют на производительность приложения.
  • Отладчик кадров позволяет остановить воспроизведение запущенной игры на определенном кадре, а затем просмотреть отдельные вызовы рисования, используемые для рендеринга этого кадра. Помимо перечисления вызовов рисования, отладчик позволяет выполнять их по очереди, чтобы вы могли увидеть, как сцена строится из графических элементов.
  • Пакет Profiling Core предоставляет API для добавления контекстной информации к захватам Unity Profiler.
Как использовать инструменты

Стив МакГреал, старший инженер Unity и соавтор нашей электронной книги о продвинутом профилировании, подготовил следующий обзор высокого уровня. Пожалуйста, не стесняйтесь использовать его в качестве справочного листа.

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

Блок-схема использования профилировщика для определения того, на чем следует сосредоточить усилия по оптимизации
Как использовать профилировщик для определения того, на чем следует сосредоточить усилия по оптимизации

Скачать PDF-версию этой таблицы можно здесь. Более подробную информацию вы найдете в конце этой заметки в ссылках на ресурсы, посвященные использованию каждого из инструментов профилирования.

Укладываетесь ли вы в рамки бюджета?

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

Например, у вас может быть игра, которая во время выполнения рендерит 59 кадров за 0,75 секунды, а на рендеринг следующего кадра уходит 0,25 секунды. Средняя частота смены кадров в 60 fps звучит неплохо, но на деле игроки заметят эффект заикания, поскольку на рендеринг последнего кадра уходит четверть секунды.

Стремитесь к определенному бюджету времени на кадр при профилировании и оптимизации игры, так как это имеет решающее значение для создания плавного и последовательного опыта игрока. Каждый кадр будет иметь временной бюджет, основанный на целевом fps. Приложение, нацеленное на 30 кадров в секунду, всегда должно занимать менее 33,33 мс на кадр (1000 мс / 30 кадров в секунду). Аналогично, при скорости 60 кадров в секунду на один кадр приходится 16,66 мс.

Большинство современных игр для консолей и ПК стремятся к частоте кадров 60 fps и выше. В VR-играх на самом деле важнее избегать регулярно высокой частоты кадров, поскольку это может вызвать тошноту или дискомфорт у игроков. Мобильные игры также могут требовать ограниченного бюджета кадров, чтобы не перегревать устройства, на которых они работают. Например, мобильная игра может быть нацелена на 30 кадров в секунду с бюджетом кадра всего 21-22 мс, чтобы CPU и GPU успевали остыть между кадрами.

Используйте Unity Profiler, чтобы узнать, укладываетесь ли вы в рамки бюджета. Ниже приведено изображение профилирующего захвата из мобильной игры Unity с постоянной профилировкой и оптимизацией. Игра поддерживает 60 кадров в секунду на мобильных телефонах с высоким разрешением и 30 кадров в секунду на телефонах со средним/низким разрешением, как, например, на этом снимке:

Снимок частоты кадров в профилировщике
Снимок частоты кадров в профилировщике

Игра работает в пределах ~22 мс, необходимых для 30 кадров в секунду, и не перегревается. Обратите внимание на подстановку WaitForTargetfps в основной поток, вплоть до VSync, и на серые времена простоя в потоке рендеринга и рабочем потоке. Кроме того, обратите внимание на интервал VBlank, посмотрев на время окончания Gfx. Присутствие кадра за кадром рисует временную шкалу в области Timeline или на линейке Time вверху, чтобы отмерять время от одного до другого.

Если вы уложились в бюджет кадра, включая все корректировки, сделанные для учета расхода батареи и теплового дросселирования, то вы успешно завершили профилирование производительности до следующего раза - поздравляем! Теперь посмотрите на использование памяти, чтобы убедиться, что оно также находится в рамках бюджета.

Однако если ваша игра не укладывается в рамки бюджета, следующим шагом будет выявление узкого места. Другими словами, выясните, на что уходит больше времени - на CPU или GPU. Если дело в процессоре, определите, какой поток наиболее загружен - в нем и кроется узкое место.

Смысл профилирования заключается в том, чтобы выявить узкие места, которые можно оптимизировать. Если вы полагаетесь на догадки, то можете оптимизировать те части игры, которые не являются узкими местами, что приведет к незначительным улучшениям или вообще к их отсутствию. Некоторые "оптимизации" могут даже ухудшить общую производительность игры.

Вы привязаны к основному потоку процессора?

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

На скриншоте ниже показан пример того, как выглядит проект, привязанный к основному потоку:

Захват из проекта, привязанного к главному потоку

Хотя потоки рендеринга и рабочие потоки выглядят как в предыдущем примере, который находится в пределах бюджета кадра, главный поток здесь явно занят работой на протяжении всего кадра. Даже если учесть небольшое количество накладных расходов Profiler в конце кадра, основной поток занят более 45 мс, что означает, что этот проект достигает частоты кадров менее 22 fps. Нет никаких маркеров, показывающих, что главный поток бездействует в ожидании VSync; он занят в течение всего кадра.

Следующий этап расследования - выявление частей кадра, которые занимают больше всего времени, и определение причин, лежащих в их основе. Используйте Unity Profiler и Profile Analyzer для оценки и устранения самых больших затрат. Часто узкими местами являются физика, неоптимизированные скрипты, сборщик мусора (GC), анимация, камеры и пользовательский интерфейс. Если источник проблемы не очевиден сразу, попробуйте включить глубокое профилирование, стеки вызовов или использовать собственный профилировщик процессора.

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

Вы привязаны к потоку рендеринга процессора?

В процессе рендеринга главный поток изучает сцену и выполняет сортировку камер, сортировку глубины и пакетную обработку вызовов рисования, чтобы составить список объектов для рендеринга. Этот список передается потоку рендеринга, который переводит его из внутреннего представления Unity, не зависящего от платформы, в вызовы графического API, необходимые для работы с GPU на конкретной платформе.

В захвате Profiler, показанном ниже, видно, что основной поток ожидает поток рендеринга, прежде чем начать рендеринг текущего кадра, на что указывает маркер Gfx.WaitForPresentOnGfxThreadmarker.

Сценарий рендеринга с привязкой к потоку в Profiler
Сценарий рендеринга с привязкой к потоку в Profiler

Поток рендеринга все еще подает команды вызова рисования с предыдущего кадра, но еще не готов принимать новые вызовы рисования от основного потока. Поток рендеринга проводит время в Camera.Render.

Модуль Rendering Profiler предоставляет обзор количества пакетов вызовов рисования и вызовов SetPass для каждого кадра. Лучшим инструментом для выяснения того, какой вызов draw передает проблемы потока рендеринга на GPU, является Frame Debugger. К распространенным причинам узких мест в потоке рендеринга относятся плохое пакетирование вызовов рисования, наличие нескольких активных камер в сцене и неэффективная очистка камеры.

Связаны ли вы рабочими потоками процессора?

Привязанность к потокам процессора, помимо основного потока или потока рендеринга, - не такая уж частая проблема, но она может возникнуть в проектах, использующих стек технологий, ориентированных на данные (DOTS), - особенно если работа переносится с основного потока на рабочие потоки с помощью системы заданий C#.

Вот снимок из режима Play в редакторе, на котором показан проект DOTS, выполняющий симуляцию жидкости с частицами на CPU:

Проект на основе DOTS, с большим количеством симуляций, связанный рабочими потоками

Как вы можете видеть, рабочие потоки плотно заполнены заданиями. Это говорит о том, что большой объем работы смещен с основного потока. Обратите внимание, что время кадра 48,14 мс и серый маркер WaitForJobGroupID 35,57 мс в главном потоке указывают на то, что рабочие потоки выполняют больше работы, чем реально может быть выполнено за один кадр на данном процессоре.

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

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

Вы можете использовать функцию Flow Events в представлении Timeline модуля CPU Usage Profiler, чтобы увидеть, когда задания запланированы и когда их результаты ожидаются главным потоком. Более подробную информацию о написании эффективного кода DOTS можно найти в наших лучших практиках DOTS.

Вы привязаны к графическому процессору?

Вы можете заметить, что ваш основной поток тратит время на ожидание потока рендеринга (об этом свидетельствуют маркеры Profiler, такие как Gfx.WaitForPresentOnGfxThread). Но в то же время ваш поток рендеринга может отображать такие маркеры, как Gfx.PresentFrame или <GraphicsAPIName>.WaitForLastPresent. Это означает, что ваше приложение привязано к GPU. Поэтому для повышения общей производительности вам придется сосредоточить усилия по оптимизации на узких местах GPU.

Следующий снимок был сделан на Samsung Galaxy S7 с использованием графического API Vulkan. Хотя часть времени, проведенного в Gfx.PresentFrame в этом примере, может быть связана с ожиданием VSync, экстремальная продолжительность этого маркера Profiler доказывает, что большая часть времени уходит на ожидание завершения рендеринга предыдущего кадра графическим процессором.

Захват из мобильной игры, работающей на GPU
Захват из мобильной игры, работающей на GPU

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

Чтобы тщательно исследовать причину узких мест в работе GPU, изучите захват GPU с помощью подходящего GPU Profiler. Инструмент, который вы используете, зависит от целевого оборудования и выбранного графического API.

К распространенным причинам низкой производительности GPU относятся неэффективные шейдеры, дорогие эффекты постобработки, прозрачная перерисовка (часто от эффектов частиц или пользовательского интерфейса), большие или несжатые текстуры, сетки с чрезмерно большим количеством полигонов и чрезмерное разрешение вывода (например, рендеринг в 4K).

Получите бесплатную электронную книгу
Продвижение профилирующей электронной книги
Электронная книга "Ultimate guide to profiling unity games"

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

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

Если вам интересно узнать, как ваша команда может получить прямой доступ к инженерам, консультациям экспертов и руководству проектом, ознакомьтесь с планами успеха Unity здесь.

Вебинар по профилированию
3D-модель с фигуркой робота справа

Настройтесь на наш новый вебинар Ultimate profiling tips с участием экспертов из SYBO Games, Arm и Unity, чтобы узнать, как выявить общие проблемы производительности в мобильных играх, используя как Unity, так и собственные инструменты профилирования.

На этом вебинаре будут рассмотрены следующие вопросы:

  • Ключевые соображения для создания экономичного, производительного кода и оптимизации использования памяти для плавной работы на устройствах низкого и высокого класса
  • Управление тепловым режимом для экономии драгоценных циклов работы аккумулятора в мобильных устройствах
  • Профилирующие стратегии на всех этапах разработки игры и способы их тестирования для создания надежной методологии
  • Экспертные знания о профилировании Android

Присоединяйтесь к нашему круглому столу и живым вопросам и ответам 14 июня 2022 года в 11:00 утра по восточному времени / 8:00 утра по тихоокеанскому времени.

Не нашли то, что искали?

Мы хотим помочь вам извлечь максимум пользы из приложений Unity. Если вы хотите, чтобы мы продолжили изучение темы оптимизации, сообщите нам об этом на форумах. Мы также хотели бы узнать, какие форматы вы предпочитаете, чтобы мы могли улучшить наши электронные книги и другие учебные материалы.