Профилирование с помощью приборов

IAND / UNITY TECHNOLOGIESContributor
Feb 1, 2016|6 Мин
Профилирование с помощью приборов
Эта веб-страница была переведена с помощью машинного перевода для вашего удобства. Мы не можем гарантировать точность или надежность переведенного контента. Если у вас есть вопросы о точности переведенного контента, обращайтесь к официальной английской версии веб-страницы.

В команде поддержки предприятий мы видим много проектов, связанных с iOS. В какой-то момент при разработке iOS разработчики часто запускают свою игру и сидят и думают: "Почему, черт возьми, она так медленно работает?". Существует несколько отличных наборов инструментов для анализа производительности, и один из лучших - Instruments. Читайте далее, чтобы узнать, как использовать его для поиска своих проблем!

Чтобы использовать Instruments или любой из инструментов отладки XCode, вам нужно собрать проект Unity для iOS Build Target (с опциями Development Build и Script Debugging, снятыми с флажков). Затем вам нужно будет скомпилировать полученный проект XCode в режиме Release и развернуть его на подключенном устройстве iOS.

Запустив Instruments (либо длительным нажатием на кнопку воспроизведения, либо выбрав Products>Profile), выберите Time Profiler. Чтобы начать прогон профилирования, выберите собранное приложение в селекторе приложений, а затем нажмите красную кнопку Record. Приложение запустится на устройстве iOS с подключенными приборами, и Time Profiler начнет записывать телеметрию. Телеметрия появится в виде синего графика на временной шкале инструментов.

blogpic

P.S. Чтобы очистить иерархию вызовов, нажмите кнопку Call Tree в левом нижнем углу панели Details, чтобы отобразить опции, и выберите Flatten Recursion и Hide System Libraries.

изображение

Список вызовов методов появится в разделе "Детали" окна "Инструменты". Каждый вызов метода верхнего уровня представляет собой поток в приложении.

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

Развернув метод main, вы получите глубокое дерево вызовов методов. Основное ответвление находится между двумя методами:

  • [startUnity] и UnityLoadApplication (имена этих методов иногда пишутся ALL CAPS).
  • PlayerLoop

[startUnity] представляет интерес, поскольку содержит все время, затраченное на инициализацию движка Unity. Под ним находится метод с именем UnityLoadApplication. Именно под UnityLoadApplication можно профилировать время запуска.

изображение00

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

Инструменты также можно использовать для поиска широко распространенных поглотителей производительности - тех, которые не имеют одной большой горячей точки, а проявляются в виде нескольких миллисекунд потерянного времени во многих разных местах кодовой базы. Для этого введите частичное или полное имя функции в поле поиска символов Instruments, которое можно увидеть, нажав ⌘F или выбрав пункт Найти/Найти... в меню Правка. Если вы профилируете фрагмент игрового процесса, разверните PlayerLoop и сверните все методы под ним. Если вы профилируете время запуска, разверните UnityLoadApplication и сверните методы под ним. Общее количество миллисекунд, потраченных на конкретную операцию, можно приблизительно оценить, посмотрев общее время, проведенное в PlayerLoop или UnityLoadApplication, и вычтя количество миллисекунд, расположенное в колонке self.

Общие методы поиска:

  • "Box(", "box" и "box" - указывают на то, что в C# имеет место боксирование значений; большинство случаев боксирования тривиально фиксированы
  • "Concat" - конкатенация строк часто легко оптимизируется.
  • "CreateScriptingArray" - Все API Unity, возвращающие массивы, будут выделять новые копии массивов. Сведите к минимуму вызовы этих методов.
  • "Отражение" - отражение медленное. Используйте это, чтобы оценить время, потерянное на размышления, и устранить его, где это возможно.
  • "FindObjectOfType" - Используйте его для поиска повторяющихся или ненужных вызовов FindObjectOfType или других известных медленных API Unity.
  • "Linq" - Изучите время, потерянное на создание и отбрасывание запросов Linq; рассмотрите возможность замены "горячих точек" методами, оптимизированными вручную.

Помимо профилирования процессорного времени, Instruments также позволяет профилировать использование памяти. Профилировщик Allocations компании Instruments предоставляет два зонда, которые позволяют получить подробное представление об использовании памяти приложением. Зонд Allocations позволяет проверить объекты, находящиеся в памяти в течение определенного промежутка времени. Зонд VM Tracker позволяет отслеживать размер кучи грязной памяти, которая является основной метрикой, используемой iOS для определения момента, когда приложение должно быть принудительно закрыто.

При выборе профилировщика Allocations в Instruments оба зонда будут запущены одновременно. Как обычно, начните прогон профилирования, нажав красную кнопку Record.

Чтобы правильно настроить зонд распределения, убедитесь в правильности следующих параметров. В нижней части окна убедитесь, что для параметра Allocation Lifespan (средний параметр) установлено значение Created & Persistent (Создано и постоянно). В Параметры записи (меню Файл) убедитесь, что установлен флажок Отбрасывать события для освобожденной памяти.

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

Еще один полезный дисплей - это дисплей Call Trees. Он отображает строку кода, в которой выполняются выделения, а также объем памяти, за который отвечает эта строка. Вы можете изменить отображение, нажав справа от "Подробностей", как показано здесь:

изображение

Ниже вы можете видеть, что около 25 % общего объема используемой памяти тестируемого приложения приходится исключительно на шейдеры. Учитывая расположение шейдеров в потоке загрузки, это должны быть стандартные шейдеры, поставляемые с проектами Unity по умолчанию, которые затем загружаются при запуске приложения.

изображение01

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

Вот так. Краткое руководство по инструментам. 1000 (около) слов и никаких отсылок к A-Team. Мы не хотим попасть в неприятности, как в прошлый раз. Нарушение авторских прав официально не является смешным.

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

Мы любим, когда план воплощается в жизнь.