Производительность unity3d: подводные камни / Алексей...

90
Производительность Unity3D: подводные камни Алексей Чубарь, BIT.GAMES

Upload: ontico

Post on 16-Apr-2017

298 views

Category:

Engineering


16 download

TRANSCRIPT

Page 1: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Производительность Unity3D подводные камниАлексей Чубарь BITGAMES

Unity3D

Рендеринг

Анимации

Звук

Физика

Редактор

Оптимизация

hellip

Alexey Chubar
Что такое Unity Это игровой движок которым многие пользуются он много чего умеет из коробки Это значительно упрощает процесс разработки игры ускоряет прототипирование позволяет сконцентрироваться непосредственно на игровом функционале а не на низкоуровневых подсистемах приложения

Unity3D

Alexey Chubar
Все сущности представляются в виде тн игровых объектов - Game Objects Все возможные свойства этих объектов описываются набором компонентов прикреплённых к объекту Пример - объект Гремлин компоненты отвечают за вид анимацию поведение и игровые характеристики Гремлина

Unity3D

Alexey Chubar
С помощью визуального редактора Unity игровые объекты настраиваются и компонуются в иерархическую структуру Так получается игровой уровень Наша игра Гильдия Героев на которую я буду иногда опираться в рассказе - это эдакий Diablo для тех у кого нет времени Игрок путешествует по лесам полям и подземельям раздавая тумаки прихвостням главного злодея

Unity3D

Alexey Chubar
Соответственно игровой уровень в нашем случае представляет собой последовательность таких вот арен на которых игрока атакуют волны врагов злые боссы или персонажи других игроков
>

Unity3D

9 FPSШМЯК БРЯК

И В ПРОДАКШН

Alexey Chubar
Видно что уровень абстракии при таком подходе весьма высок Многое настраивается в визуальном редакторе количество низкоуровневого кода который разработчик пропускает через себя минимально В таких условиях важно не забывать как оно всё работает внутри Иначе легко сделать так что даже простые приложения будут тормозить на устройтстве у пользователя Более того некоторые действия на уровне Unity во время разработки могут иметь неожиданные и неочевидные последствия для производительности конечного продукта В данном докладе речь пойдёт о том что важно держать в голове во время разработки чтобы приложение в итоге не тормозило Помимо общих рекомендаций я поведаю о весьма неожиданных граблях на которые мы успели наступить во время разработки Гильдии Героев

Unity3D

PC amp Console games Mobile games

Architectural visualizations

Medical simulations

Military simulations

CAD

Research

Interactive presentations

hellip

Education

Media amp movies

Art installations

Alexey Chubar
Даже если вы не занимаетесь разработкой игр доклад вполне может быть полезен поскольку Unity применяется в большом количестве сфер деятельности

Unity3D

PC amp Console games Mobile games

Architectural visualizations

Medical simulations

Military simulations

CAD

Research

Interactive presentations

hellip

Education

Media amp movies

Art installations

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

Суровый мир мобильных игр

Alexey Chubar
Чем же он суров

Суровый мир мобильных игрbull Высокая конкуренция

Alexey Chubar
Благодаря вещам вроде Unity порог вхождения в индустрию весьма низок Рынок пресыщен На каждую игру можно найти 10 аналогов Чтобы игра была прибыльна она должна быть как мининум не хуже остальных И как бы она ни была хороша во всем остальном она должна быстро и стабильно работать иначе пользователь мгновенно уйдёт играть в игры конкурентов

Суровый мир мобильных игрbull Высокая конкуренцияbull Специфика аудитории

Alexey Chubar
Заметная часть пользователей (особенно на Google Play) любит купить китайский планшет за 3 тыщи рублей и потом винить разработчиков игр в том что у них всё тормозит (даже если игра выдаёт больше кадров в секунду чем главное меню их аппарата) Многие из покупателей бюджетных устройств конечно сознательны и понимают что дело в их устройстве и не пишут негативных отзывов на игру Но остальные не упустят возможности поставить 1 звёздочку В обоих случаях вы теряете пользователя Однако во втором случае вы теряете вдобавок ещё и будущих потенциальных пользователей которые зайдя на страницу игры видят негатив и предпочитают вашу игру не качать
Alexey Chubar
Поэтому надо сделать так чтобы у обладателей топовых устройств было красиво и быстро у обладателей бюджетных - хотя бы играбельно При этом в большинстве своём аудитория казуальная поэтому сделать огромное меню настройки графики как в ПК-играх - не вариант

Суровый мир мобильных игрbull Высокая конкуренцияbull Специфика аудиторииbull Специфика программно-аппаратной платформы

Alexey Chubar
Вдобавок программно-аппаратная начинка мобильных устройств имеет ряд важных отличий от консолей и ПК О них нужно сказать поподробнее чтобы понять с чем мы вообще имеем дело Android- и iOS-устройства несмотря на все свои различия разделяют часть важных с точки зрения разработки принципов

Что там внутриbull Какой-то странный процессорbull ARM x86 MIPShellip 32 и 64 bit

Alexey Chubar
Начнём с аппаратной начинки Современные флагманские устройства имееют поистине впечатляющие характеристики Много ядер много гигагерцев много гигабайт оперативки и так далее Однако когда мы слышим что выходит очередной смартфон с 8-ядерным процессором 25 ГГц мы конечно понимаем что это мягко говоря не то же самое что 8-ядерный Core i7

bull Какой-то странный процессорbull ARM x86 MIPShellip 32 и 64 bit

Что там внутри

ne

Alexey Chubar
Большинство устройств основаны на микроархитектуре ARMv7 которая значительно отличается от x86 Изначально это RISC-архитектура поэтому некоторые алгоритмы с которыми настольный компьютер справляется легко благодаря куче инструкций на все случаи жизни и SIMD-расширениями могут работать на ARM-процессоре куда медленнее

Что там внутриbull Какая-то батарейка

Alexey Chubar
Причина различий в производительности с настольными системами конечно понятна - это необходимость компактого размера и скромного энергопотребления Однако высокая нагрузка на процессор и интенсивный обмен данными по сети всё равно быстро посадят любой аккумулятор Если ваша игра будет разряжать телефон за час никто вас любить не будет Включая Google и Apple которые всё жестче следят за энергопотреблением приложений Поэтому следует оптимизировать игру минимизируя нагрузку на ЦП и обмен данными

Что там внутриbull Какой-то графический ускоритель

ne

Alexey Chubar
Да в телефонах есть что-то вроде видеокарты Но опять же это не совсем 250-ваттный GeForce Графические ускорители в мобильных устройствах имееют ряд особенностей которые важно понимать для достижения высокой производительности О них я подробнее расскажу ниже

Что там внутриbull Какая-то оперативная памятьbull Её всегда мало

Alexey Chubar
Одна из таких особенностей - отсутствие собственной видеопамяти Для своих нужд графический процессор использует часть оперативной памяти устройства И это дополнительно осложняет жизнь разработчику потому что оперативной памяти вечно не хватает Не хватает её в частности из-за специфики мобильных ОС Даже если ты работаешь с флагманом у которого 3-4 гигабайта оперативки это не значит что твоё приложение может выжрать все эти 3 гига Мобильная ОС не церемонится с приложениями которые потребляют много памяти Она завершает их работу как только ей понадобится память для других задач Если приложение наглеет система может втихую прибить его даже если оно сейчас открыто и пользователь на него смотрит Однако ещё до этого с ростом потребления памяти производительность приложения будет падать так как ему будет всё сложнее найти свободный участок памяти для каких-либо сиюминутных вычислений и операций Поэтому нужно очень аккуратно работать с оперативной памятью

Зоопарк устройств

Alexey Chubar
Я не случайно говорил какой-токакая-то на предыдущих слайдах Аппаратных конфигураций в итоге получается очень много На рынке находится целый зоопарк устройств И чтобы завладеть максимальной аудиторией болшинство устрйоств нужно поддерживать Считалось что фрагментация - удел Android однако сейчас и у Apple накопилось значительное число устровйств на базе iOS При этом вопреки стереотипам далеко не все обладатели айфонов и айпадов каждый год меняют свой девайс на новый Многие играют на iPad 2 и iPad Mini 1st Gen где всего 512 МБ ОЗУ

Зоопарк устройств

240 MB ought to be enough for anyone ndash Gill Bates

Alexey Chubar
Эмпирически мы выявили лимит потребления памяти игрой позволяющий её работать на устройствах с 512 Мб ОЗУ - примерно 240 МБ памяти Сюда соответственно входит и динамическая память приложения и текстуры и звук и проч Это довольно жесткое ограничение которое легко нарушить

bull Падение FPSbull Чёрные квадраты вместо текстурbull laquoТихоеraquo завершение приложения без отчёта об ошибке

Зоопарк устройств

gt240 MB

Alexey Chubar
При привышении этого лимита на слабых девайсах наблюдаются неприятные эффекты

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Alexey Chubar
В таких суровых условиях на ум приходит одна общая рекомендация которая уже сформулирована в документации Unity

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Постоянно спрашивай себя ldquoА не ерунду ли я сейчас делаюrdquo- Примерный перевод

Alexey Chubar
В голове нужно постоянно держать возможные последствия своих действий для производительности игры на мобильном устройстве И разрабатывать игру сразу с учётом жестких требований Рассмотрим же какие конкретные аспекты игры влияют на производительность

Из-за чего всё тормозит

Alexey Chubar
Что же в нашей игре нагружает процессор жрёт память и мучает видеокарту Из-за чего приложение работает не так быстро как хотелось бы Причины вполне ожидаемые

Из-за чего всё тормозитbull Код

Alexey Chubar
Во-первых из-за того как написан вами программный код При этом здесь я не говорю о том что криво написанный код работает медленно Это и так понятно В случае с Unity порой прямо написанный код работает медленно И его приходится переписывать более криво

Из-за чего всё тормозитbull Код bull Ресурсы

Alexey Chubar
Во-вторых из-за неоптимального использования игровых ресурсов таких как 3D-модели текстуры анимации звуки и прочее

Импорт ресурсов

Alexey Chubar
Начнём с того что попроще - с игровых ресурсов Чтобы импортировать ресурс в проект Unity достаточно просто положить его в папку с проектом На слайде скриншот с их сайта И это действительно круто Однако настройки импорта по умолчанию зачастую не оптимальны особенно для мобильного приложения

Импорт ресурсов звук

Alexey Chubar
Это легко показать на примере звуков Вы кидаете MP3-мелодию в проект включаете её проигрывание на сцене всё работает Однако однажды мы вдруг обнаружили что звуки на уровне в игре занимают целых 30 МБ Притом что озвучка в принципе скромная звуки ударов и умений пара вскриков музыкальная тема и эмбиент

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 2: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Unity3D

Рендеринг

Анимации

Звук

Физика

Редактор

Оптимизация

hellip

Alexey Chubar
Что такое Unity Это игровой движок которым многие пользуются он много чего умеет из коробки Это значительно упрощает процесс разработки игры ускоряет прототипирование позволяет сконцентрироваться непосредственно на игровом функционале а не на низкоуровневых подсистемах приложения

Unity3D

Alexey Chubar
Все сущности представляются в виде тн игровых объектов - Game Objects Все возможные свойства этих объектов описываются набором компонентов прикреплённых к объекту Пример - объект Гремлин компоненты отвечают за вид анимацию поведение и игровые характеристики Гремлина

Unity3D

Alexey Chubar
С помощью визуального редактора Unity игровые объекты настраиваются и компонуются в иерархическую структуру Так получается игровой уровень Наша игра Гильдия Героев на которую я буду иногда опираться в рассказе - это эдакий Diablo для тех у кого нет времени Игрок путешествует по лесам полям и подземельям раздавая тумаки прихвостням главного злодея

Unity3D

Alexey Chubar
Соответственно игровой уровень в нашем случае представляет собой последовательность таких вот арен на которых игрока атакуют волны врагов злые боссы или персонажи других игроков
>

Unity3D

9 FPSШМЯК БРЯК

И В ПРОДАКШН

Alexey Chubar
Видно что уровень абстракии при таком подходе весьма высок Многое настраивается в визуальном редакторе количество низкоуровневого кода который разработчик пропускает через себя минимально В таких условиях важно не забывать как оно всё работает внутри Иначе легко сделать так что даже простые приложения будут тормозить на устройтстве у пользователя Более того некоторые действия на уровне Unity во время разработки могут иметь неожиданные и неочевидные последствия для производительности конечного продукта В данном докладе речь пойдёт о том что важно держать в голове во время разработки чтобы приложение в итоге не тормозило Помимо общих рекомендаций я поведаю о весьма неожиданных граблях на которые мы успели наступить во время разработки Гильдии Героев

Unity3D

PC amp Console games Mobile games

Architectural visualizations

Medical simulations

Military simulations

CAD

Research

Interactive presentations

hellip

Education

Media amp movies

Art installations

Alexey Chubar
Даже если вы не занимаетесь разработкой игр доклад вполне может быть полезен поскольку Unity применяется в большом количестве сфер деятельности

Unity3D

PC amp Console games Mobile games

Architectural visualizations

Medical simulations

Military simulations

CAD

Research

Interactive presentations

hellip

Education

Media amp movies

Art installations

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

Суровый мир мобильных игр

Alexey Chubar
Чем же он суров

Суровый мир мобильных игрbull Высокая конкуренция

Alexey Chubar
Благодаря вещам вроде Unity порог вхождения в индустрию весьма низок Рынок пресыщен На каждую игру можно найти 10 аналогов Чтобы игра была прибыльна она должна быть как мининум не хуже остальных И как бы она ни была хороша во всем остальном она должна быстро и стабильно работать иначе пользователь мгновенно уйдёт играть в игры конкурентов

Суровый мир мобильных игрbull Высокая конкуренцияbull Специфика аудитории

Alexey Chubar
Заметная часть пользователей (особенно на Google Play) любит купить китайский планшет за 3 тыщи рублей и потом винить разработчиков игр в том что у них всё тормозит (даже если игра выдаёт больше кадров в секунду чем главное меню их аппарата) Многие из покупателей бюджетных устройств конечно сознательны и понимают что дело в их устройстве и не пишут негативных отзывов на игру Но остальные не упустят возможности поставить 1 звёздочку В обоих случаях вы теряете пользователя Однако во втором случае вы теряете вдобавок ещё и будущих потенциальных пользователей которые зайдя на страницу игры видят негатив и предпочитают вашу игру не качать
Alexey Chubar
Поэтому надо сделать так чтобы у обладателей топовых устройств было красиво и быстро у обладателей бюджетных - хотя бы играбельно При этом в большинстве своём аудитория казуальная поэтому сделать огромное меню настройки графики как в ПК-играх - не вариант

Суровый мир мобильных игрbull Высокая конкуренцияbull Специфика аудиторииbull Специфика программно-аппаратной платформы

Alexey Chubar
Вдобавок программно-аппаратная начинка мобильных устройств имеет ряд важных отличий от консолей и ПК О них нужно сказать поподробнее чтобы понять с чем мы вообще имеем дело Android- и iOS-устройства несмотря на все свои различия разделяют часть важных с точки зрения разработки принципов

Что там внутриbull Какой-то странный процессорbull ARM x86 MIPShellip 32 и 64 bit

Alexey Chubar
Начнём с аппаратной начинки Современные флагманские устройства имееют поистине впечатляющие характеристики Много ядер много гигагерцев много гигабайт оперативки и так далее Однако когда мы слышим что выходит очередной смартфон с 8-ядерным процессором 25 ГГц мы конечно понимаем что это мягко говоря не то же самое что 8-ядерный Core i7

bull Какой-то странный процессорbull ARM x86 MIPShellip 32 и 64 bit

Что там внутри

ne

Alexey Chubar
Большинство устройств основаны на микроархитектуре ARMv7 которая значительно отличается от x86 Изначально это RISC-архитектура поэтому некоторые алгоритмы с которыми настольный компьютер справляется легко благодаря куче инструкций на все случаи жизни и SIMD-расширениями могут работать на ARM-процессоре куда медленнее

Что там внутриbull Какая-то батарейка

Alexey Chubar
Причина различий в производительности с настольными системами конечно понятна - это необходимость компактого размера и скромного энергопотребления Однако высокая нагрузка на процессор и интенсивный обмен данными по сети всё равно быстро посадят любой аккумулятор Если ваша игра будет разряжать телефон за час никто вас любить не будет Включая Google и Apple которые всё жестче следят за энергопотреблением приложений Поэтому следует оптимизировать игру минимизируя нагрузку на ЦП и обмен данными

Что там внутриbull Какой-то графический ускоритель

ne

Alexey Chubar
Да в телефонах есть что-то вроде видеокарты Но опять же это не совсем 250-ваттный GeForce Графические ускорители в мобильных устройствах имееют ряд особенностей которые важно понимать для достижения высокой производительности О них я подробнее расскажу ниже

Что там внутриbull Какая-то оперативная памятьbull Её всегда мало

Alexey Chubar
Одна из таких особенностей - отсутствие собственной видеопамяти Для своих нужд графический процессор использует часть оперативной памяти устройства И это дополнительно осложняет жизнь разработчику потому что оперативной памяти вечно не хватает Не хватает её в частности из-за специфики мобильных ОС Даже если ты работаешь с флагманом у которого 3-4 гигабайта оперативки это не значит что твоё приложение может выжрать все эти 3 гига Мобильная ОС не церемонится с приложениями которые потребляют много памяти Она завершает их работу как только ей понадобится память для других задач Если приложение наглеет система может втихую прибить его даже если оно сейчас открыто и пользователь на него смотрит Однако ещё до этого с ростом потребления памяти производительность приложения будет падать так как ему будет всё сложнее найти свободный участок памяти для каких-либо сиюминутных вычислений и операций Поэтому нужно очень аккуратно работать с оперативной памятью

Зоопарк устройств

Alexey Chubar
Я не случайно говорил какой-токакая-то на предыдущих слайдах Аппаратных конфигураций в итоге получается очень много На рынке находится целый зоопарк устройств И чтобы завладеть максимальной аудиторией болшинство устрйоств нужно поддерживать Считалось что фрагментация - удел Android однако сейчас и у Apple накопилось значительное число устровйств на базе iOS При этом вопреки стереотипам далеко не все обладатели айфонов и айпадов каждый год меняют свой девайс на новый Многие играют на iPad 2 и iPad Mini 1st Gen где всего 512 МБ ОЗУ

Зоопарк устройств

240 MB ought to be enough for anyone ndash Gill Bates

Alexey Chubar
Эмпирически мы выявили лимит потребления памяти игрой позволяющий её работать на устройствах с 512 Мб ОЗУ - примерно 240 МБ памяти Сюда соответственно входит и динамическая память приложения и текстуры и звук и проч Это довольно жесткое ограничение которое легко нарушить

bull Падение FPSbull Чёрные квадраты вместо текстурbull laquoТихоеraquo завершение приложения без отчёта об ошибке

Зоопарк устройств

gt240 MB

Alexey Chubar
При привышении этого лимита на слабых девайсах наблюдаются неприятные эффекты

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Alexey Chubar
В таких суровых условиях на ум приходит одна общая рекомендация которая уже сформулирована в документации Unity

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Постоянно спрашивай себя ldquoА не ерунду ли я сейчас делаюrdquo- Примерный перевод

Alexey Chubar
В голове нужно постоянно держать возможные последствия своих действий для производительности игры на мобильном устройстве И разрабатывать игру сразу с учётом жестких требований Рассмотрим же какие конкретные аспекты игры влияют на производительность

Из-за чего всё тормозит

Alexey Chubar
Что же в нашей игре нагружает процессор жрёт память и мучает видеокарту Из-за чего приложение работает не так быстро как хотелось бы Причины вполне ожидаемые

Из-за чего всё тормозитbull Код

Alexey Chubar
Во-первых из-за того как написан вами программный код При этом здесь я не говорю о том что криво написанный код работает медленно Это и так понятно В случае с Unity порой прямо написанный код работает медленно И его приходится переписывать более криво

Из-за чего всё тормозитbull Код bull Ресурсы

Alexey Chubar
Во-вторых из-за неоптимального использования игровых ресурсов таких как 3D-модели текстуры анимации звуки и прочее

Импорт ресурсов

Alexey Chubar
Начнём с того что попроще - с игровых ресурсов Чтобы импортировать ресурс в проект Unity достаточно просто положить его в папку с проектом На слайде скриншот с их сайта И это действительно круто Однако настройки импорта по умолчанию зачастую не оптимальны особенно для мобильного приложения

Импорт ресурсов звук

Alexey Chubar
Это легко показать на примере звуков Вы кидаете MP3-мелодию в проект включаете её проигрывание на сцене всё работает Однако однажды мы вдруг обнаружили что звуки на уровне в игре занимают целых 30 МБ Притом что озвучка в принципе скромная звуки ударов и умений пара вскриков музыкальная тема и эмбиент

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 3: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Unity3D

Alexey Chubar
Все сущности представляются в виде тн игровых объектов - Game Objects Все возможные свойства этих объектов описываются набором компонентов прикреплённых к объекту Пример - объект Гремлин компоненты отвечают за вид анимацию поведение и игровые характеристики Гремлина

Unity3D

Alexey Chubar
С помощью визуального редактора Unity игровые объекты настраиваются и компонуются в иерархическую структуру Так получается игровой уровень Наша игра Гильдия Героев на которую я буду иногда опираться в рассказе - это эдакий Diablo для тех у кого нет времени Игрок путешествует по лесам полям и подземельям раздавая тумаки прихвостням главного злодея

Unity3D

Alexey Chubar
Соответственно игровой уровень в нашем случае представляет собой последовательность таких вот арен на которых игрока атакуют волны врагов злые боссы или персонажи других игроков
>

Unity3D

9 FPSШМЯК БРЯК

И В ПРОДАКШН

Alexey Chubar
Видно что уровень абстракии при таком подходе весьма высок Многое настраивается в визуальном редакторе количество низкоуровневого кода который разработчик пропускает через себя минимально В таких условиях важно не забывать как оно всё работает внутри Иначе легко сделать так что даже простые приложения будут тормозить на устройтстве у пользователя Более того некоторые действия на уровне Unity во время разработки могут иметь неожиданные и неочевидные последствия для производительности конечного продукта В данном докладе речь пойдёт о том что важно держать в голове во время разработки чтобы приложение в итоге не тормозило Помимо общих рекомендаций я поведаю о весьма неожиданных граблях на которые мы успели наступить во время разработки Гильдии Героев

Unity3D

PC amp Console games Mobile games

Architectural visualizations

Medical simulations

Military simulations

CAD

Research

Interactive presentations

hellip

Education

Media amp movies

Art installations

Alexey Chubar
Даже если вы не занимаетесь разработкой игр доклад вполне может быть полезен поскольку Unity применяется в большом количестве сфер деятельности

Unity3D

PC amp Console games Mobile games

Architectural visualizations

Medical simulations

Military simulations

CAD

Research

Interactive presentations

hellip

Education

Media amp movies

Art installations

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

Суровый мир мобильных игр

Alexey Chubar
Чем же он суров

Суровый мир мобильных игрbull Высокая конкуренция

Alexey Chubar
Благодаря вещам вроде Unity порог вхождения в индустрию весьма низок Рынок пресыщен На каждую игру можно найти 10 аналогов Чтобы игра была прибыльна она должна быть как мининум не хуже остальных И как бы она ни была хороша во всем остальном она должна быстро и стабильно работать иначе пользователь мгновенно уйдёт играть в игры конкурентов

Суровый мир мобильных игрbull Высокая конкуренцияbull Специфика аудитории

Alexey Chubar
Заметная часть пользователей (особенно на Google Play) любит купить китайский планшет за 3 тыщи рублей и потом винить разработчиков игр в том что у них всё тормозит (даже если игра выдаёт больше кадров в секунду чем главное меню их аппарата) Многие из покупателей бюджетных устройств конечно сознательны и понимают что дело в их устройстве и не пишут негативных отзывов на игру Но остальные не упустят возможности поставить 1 звёздочку В обоих случаях вы теряете пользователя Однако во втором случае вы теряете вдобавок ещё и будущих потенциальных пользователей которые зайдя на страницу игры видят негатив и предпочитают вашу игру не качать
Alexey Chubar
Поэтому надо сделать так чтобы у обладателей топовых устройств было красиво и быстро у обладателей бюджетных - хотя бы играбельно При этом в большинстве своём аудитория казуальная поэтому сделать огромное меню настройки графики как в ПК-играх - не вариант

Суровый мир мобильных игрbull Высокая конкуренцияbull Специфика аудиторииbull Специфика программно-аппаратной платформы

Alexey Chubar
Вдобавок программно-аппаратная начинка мобильных устройств имеет ряд важных отличий от консолей и ПК О них нужно сказать поподробнее чтобы понять с чем мы вообще имеем дело Android- и iOS-устройства несмотря на все свои различия разделяют часть важных с точки зрения разработки принципов

Что там внутриbull Какой-то странный процессорbull ARM x86 MIPShellip 32 и 64 bit

Alexey Chubar
Начнём с аппаратной начинки Современные флагманские устройства имееют поистине впечатляющие характеристики Много ядер много гигагерцев много гигабайт оперативки и так далее Однако когда мы слышим что выходит очередной смартфон с 8-ядерным процессором 25 ГГц мы конечно понимаем что это мягко говоря не то же самое что 8-ядерный Core i7

bull Какой-то странный процессорbull ARM x86 MIPShellip 32 и 64 bit

Что там внутри

ne

Alexey Chubar
Большинство устройств основаны на микроархитектуре ARMv7 которая значительно отличается от x86 Изначально это RISC-архитектура поэтому некоторые алгоритмы с которыми настольный компьютер справляется легко благодаря куче инструкций на все случаи жизни и SIMD-расширениями могут работать на ARM-процессоре куда медленнее

Что там внутриbull Какая-то батарейка

Alexey Chubar
Причина различий в производительности с настольными системами конечно понятна - это необходимость компактого размера и скромного энергопотребления Однако высокая нагрузка на процессор и интенсивный обмен данными по сети всё равно быстро посадят любой аккумулятор Если ваша игра будет разряжать телефон за час никто вас любить не будет Включая Google и Apple которые всё жестче следят за энергопотреблением приложений Поэтому следует оптимизировать игру минимизируя нагрузку на ЦП и обмен данными

Что там внутриbull Какой-то графический ускоритель

ne

Alexey Chubar
Да в телефонах есть что-то вроде видеокарты Но опять же это не совсем 250-ваттный GeForce Графические ускорители в мобильных устройствах имееют ряд особенностей которые важно понимать для достижения высокой производительности О них я подробнее расскажу ниже

Что там внутриbull Какая-то оперативная памятьbull Её всегда мало

Alexey Chubar
Одна из таких особенностей - отсутствие собственной видеопамяти Для своих нужд графический процессор использует часть оперативной памяти устройства И это дополнительно осложняет жизнь разработчику потому что оперативной памяти вечно не хватает Не хватает её в частности из-за специфики мобильных ОС Даже если ты работаешь с флагманом у которого 3-4 гигабайта оперативки это не значит что твоё приложение может выжрать все эти 3 гига Мобильная ОС не церемонится с приложениями которые потребляют много памяти Она завершает их работу как только ей понадобится память для других задач Если приложение наглеет система может втихую прибить его даже если оно сейчас открыто и пользователь на него смотрит Однако ещё до этого с ростом потребления памяти производительность приложения будет падать так как ему будет всё сложнее найти свободный участок памяти для каких-либо сиюминутных вычислений и операций Поэтому нужно очень аккуратно работать с оперативной памятью

Зоопарк устройств

Alexey Chubar
Я не случайно говорил какой-токакая-то на предыдущих слайдах Аппаратных конфигураций в итоге получается очень много На рынке находится целый зоопарк устройств И чтобы завладеть максимальной аудиторией болшинство устрйоств нужно поддерживать Считалось что фрагментация - удел Android однако сейчас и у Apple накопилось значительное число устровйств на базе iOS При этом вопреки стереотипам далеко не все обладатели айфонов и айпадов каждый год меняют свой девайс на новый Многие играют на iPad 2 и iPad Mini 1st Gen где всего 512 МБ ОЗУ

Зоопарк устройств

240 MB ought to be enough for anyone ndash Gill Bates

Alexey Chubar
Эмпирически мы выявили лимит потребления памяти игрой позволяющий её работать на устройствах с 512 Мб ОЗУ - примерно 240 МБ памяти Сюда соответственно входит и динамическая память приложения и текстуры и звук и проч Это довольно жесткое ограничение которое легко нарушить

bull Падение FPSbull Чёрные квадраты вместо текстурbull laquoТихоеraquo завершение приложения без отчёта об ошибке

Зоопарк устройств

gt240 MB

Alexey Chubar
При привышении этого лимита на слабых девайсах наблюдаются неприятные эффекты

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Alexey Chubar
В таких суровых условиях на ум приходит одна общая рекомендация которая уже сформулирована в документации Unity

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Постоянно спрашивай себя ldquoА не ерунду ли я сейчас делаюrdquo- Примерный перевод

Alexey Chubar
В голове нужно постоянно держать возможные последствия своих действий для производительности игры на мобильном устройстве И разрабатывать игру сразу с учётом жестких требований Рассмотрим же какие конкретные аспекты игры влияют на производительность

Из-за чего всё тормозит

Alexey Chubar
Что же в нашей игре нагружает процессор жрёт память и мучает видеокарту Из-за чего приложение работает не так быстро как хотелось бы Причины вполне ожидаемые

Из-за чего всё тормозитbull Код

Alexey Chubar
Во-первых из-за того как написан вами программный код При этом здесь я не говорю о том что криво написанный код работает медленно Это и так понятно В случае с Unity порой прямо написанный код работает медленно И его приходится переписывать более криво

Из-за чего всё тормозитbull Код bull Ресурсы

Alexey Chubar
Во-вторых из-за неоптимального использования игровых ресурсов таких как 3D-модели текстуры анимации звуки и прочее

Импорт ресурсов

Alexey Chubar
Начнём с того что попроще - с игровых ресурсов Чтобы импортировать ресурс в проект Unity достаточно просто положить его в папку с проектом На слайде скриншот с их сайта И это действительно круто Однако настройки импорта по умолчанию зачастую не оптимальны особенно для мобильного приложения

Импорт ресурсов звук

Alexey Chubar
Это легко показать на примере звуков Вы кидаете MP3-мелодию в проект включаете её проигрывание на сцене всё работает Однако однажды мы вдруг обнаружили что звуки на уровне в игре занимают целых 30 МБ Притом что озвучка в принципе скромная звуки ударов и умений пара вскриков музыкальная тема и эмбиент

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 4: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Unity3D

Alexey Chubar
С помощью визуального редактора Unity игровые объекты настраиваются и компонуются в иерархическую структуру Так получается игровой уровень Наша игра Гильдия Героев на которую я буду иногда опираться в рассказе - это эдакий Diablo для тех у кого нет времени Игрок путешествует по лесам полям и подземельям раздавая тумаки прихвостням главного злодея

Unity3D

Alexey Chubar
Соответственно игровой уровень в нашем случае представляет собой последовательность таких вот арен на которых игрока атакуют волны врагов злые боссы или персонажи других игроков
>

Unity3D

9 FPSШМЯК БРЯК

И В ПРОДАКШН

Alexey Chubar
Видно что уровень абстракии при таком подходе весьма высок Многое настраивается в визуальном редакторе количество низкоуровневого кода который разработчик пропускает через себя минимально В таких условиях важно не забывать как оно всё работает внутри Иначе легко сделать так что даже простые приложения будут тормозить на устройтстве у пользователя Более того некоторые действия на уровне Unity во время разработки могут иметь неожиданные и неочевидные последствия для производительности конечного продукта В данном докладе речь пойдёт о том что важно держать в голове во время разработки чтобы приложение в итоге не тормозило Помимо общих рекомендаций я поведаю о весьма неожиданных граблях на которые мы успели наступить во время разработки Гильдии Героев

Unity3D

PC amp Console games Mobile games

Architectural visualizations

Medical simulations

Military simulations

CAD

Research

Interactive presentations

hellip

Education

Media amp movies

Art installations

Alexey Chubar
Даже если вы не занимаетесь разработкой игр доклад вполне может быть полезен поскольку Unity применяется в большом количестве сфер деятельности

Unity3D

PC amp Console games Mobile games

Architectural visualizations

Medical simulations

Military simulations

CAD

Research

Interactive presentations

hellip

Education

Media amp movies

Art installations

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

Суровый мир мобильных игр

Alexey Chubar
Чем же он суров

Суровый мир мобильных игрbull Высокая конкуренция

Alexey Chubar
Благодаря вещам вроде Unity порог вхождения в индустрию весьма низок Рынок пресыщен На каждую игру можно найти 10 аналогов Чтобы игра была прибыльна она должна быть как мининум не хуже остальных И как бы она ни была хороша во всем остальном она должна быстро и стабильно работать иначе пользователь мгновенно уйдёт играть в игры конкурентов

Суровый мир мобильных игрbull Высокая конкуренцияbull Специфика аудитории

Alexey Chubar
Заметная часть пользователей (особенно на Google Play) любит купить китайский планшет за 3 тыщи рублей и потом винить разработчиков игр в том что у них всё тормозит (даже если игра выдаёт больше кадров в секунду чем главное меню их аппарата) Многие из покупателей бюджетных устройств конечно сознательны и понимают что дело в их устройстве и не пишут негативных отзывов на игру Но остальные не упустят возможности поставить 1 звёздочку В обоих случаях вы теряете пользователя Однако во втором случае вы теряете вдобавок ещё и будущих потенциальных пользователей которые зайдя на страницу игры видят негатив и предпочитают вашу игру не качать
Alexey Chubar
Поэтому надо сделать так чтобы у обладателей топовых устройств было красиво и быстро у обладателей бюджетных - хотя бы играбельно При этом в большинстве своём аудитория казуальная поэтому сделать огромное меню настройки графики как в ПК-играх - не вариант

Суровый мир мобильных игрbull Высокая конкуренцияbull Специфика аудиторииbull Специфика программно-аппаратной платформы

Alexey Chubar
Вдобавок программно-аппаратная начинка мобильных устройств имеет ряд важных отличий от консолей и ПК О них нужно сказать поподробнее чтобы понять с чем мы вообще имеем дело Android- и iOS-устройства несмотря на все свои различия разделяют часть важных с точки зрения разработки принципов

Что там внутриbull Какой-то странный процессорbull ARM x86 MIPShellip 32 и 64 bit

Alexey Chubar
Начнём с аппаратной начинки Современные флагманские устройства имееют поистине впечатляющие характеристики Много ядер много гигагерцев много гигабайт оперативки и так далее Однако когда мы слышим что выходит очередной смартфон с 8-ядерным процессором 25 ГГц мы конечно понимаем что это мягко говоря не то же самое что 8-ядерный Core i7

bull Какой-то странный процессорbull ARM x86 MIPShellip 32 и 64 bit

Что там внутри

ne

Alexey Chubar
Большинство устройств основаны на микроархитектуре ARMv7 которая значительно отличается от x86 Изначально это RISC-архитектура поэтому некоторые алгоритмы с которыми настольный компьютер справляется легко благодаря куче инструкций на все случаи жизни и SIMD-расширениями могут работать на ARM-процессоре куда медленнее

Что там внутриbull Какая-то батарейка

Alexey Chubar
Причина различий в производительности с настольными системами конечно понятна - это необходимость компактого размера и скромного энергопотребления Однако высокая нагрузка на процессор и интенсивный обмен данными по сети всё равно быстро посадят любой аккумулятор Если ваша игра будет разряжать телефон за час никто вас любить не будет Включая Google и Apple которые всё жестче следят за энергопотреблением приложений Поэтому следует оптимизировать игру минимизируя нагрузку на ЦП и обмен данными

Что там внутриbull Какой-то графический ускоритель

ne

Alexey Chubar
Да в телефонах есть что-то вроде видеокарты Но опять же это не совсем 250-ваттный GeForce Графические ускорители в мобильных устройствах имееют ряд особенностей которые важно понимать для достижения высокой производительности О них я подробнее расскажу ниже

Что там внутриbull Какая-то оперативная памятьbull Её всегда мало

Alexey Chubar
Одна из таких особенностей - отсутствие собственной видеопамяти Для своих нужд графический процессор использует часть оперативной памяти устройства И это дополнительно осложняет жизнь разработчику потому что оперативной памяти вечно не хватает Не хватает её в частности из-за специфики мобильных ОС Даже если ты работаешь с флагманом у которого 3-4 гигабайта оперативки это не значит что твоё приложение может выжрать все эти 3 гига Мобильная ОС не церемонится с приложениями которые потребляют много памяти Она завершает их работу как только ей понадобится память для других задач Если приложение наглеет система может втихую прибить его даже если оно сейчас открыто и пользователь на него смотрит Однако ещё до этого с ростом потребления памяти производительность приложения будет падать так как ему будет всё сложнее найти свободный участок памяти для каких-либо сиюминутных вычислений и операций Поэтому нужно очень аккуратно работать с оперативной памятью

Зоопарк устройств

Alexey Chubar
Я не случайно говорил какой-токакая-то на предыдущих слайдах Аппаратных конфигураций в итоге получается очень много На рынке находится целый зоопарк устройств И чтобы завладеть максимальной аудиторией болшинство устрйоств нужно поддерживать Считалось что фрагментация - удел Android однако сейчас и у Apple накопилось значительное число устровйств на базе iOS При этом вопреки стереотипам далеко не все обладатели айфонов и айпадов каждый год меняют свой девайс на новый Многие играют на iPad 2 и iPad Mini 1st Gen где всего 512 МБ ОЗУ

Зоопарк устройств

240 MB ought to be enough for anyone ndash Gill Bates

Alexey Chubar
Эмпирически мы выявили лимит потребления памяти игрой позволяющий её работать на устройствах с 512 Мб ОЗУ - примерно 240 МБ памяти Сюда соответственно входит и динамическая память приложения и текстуры и звук и проч Это довольно жесткое ограничение которое легко нарушить

bull Падение FPSbull Чёрные квадраты вместо текстурbull laquoТихоеraquo завершение приложения без отчёта об ошибке

Зоопарк устройств

gt240 MB

Alexey Chubar
При привышении этого лимита на слабых девайсах наблюдаются неприятные эффекты

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Alexey Chubar
В таких суровых условиях на ум приходит одна общая рекомендация которая уже сформулирована в документации Unity

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Постоянно спрашивай себя ldquoА не ерунду ли я сейчас делаюrdquo- Примерный перевод

Alexey Chubar
В голове нужно постоянно держать возможные последствия своих действий для производительности игры на мобильном устройстве И разрабатывать игру сразу с учётом жестких требований Рассмотрим же какие конкретные аспекты игры влияют на производительность

Из-за чего всё тормозит

Alexey Chubar
Что же в нашей игре нагружает процессор жрёт память и мучает видеокарту Из-за чего приложение работает не так быстро как хотелось бы Причины вполне ожидаемые

Из-за чего всё тормозитbull Код

Alexey Chubar
Во-первых из-за того как написан вами программный код При этом здесь я не говорю о том что криво написанный код работает медленно Это и так понятно В случае с Unity порой прямо написанный код работает медленно И его приходится переписывать более криво

Из-за чего всё тормозитbull Код bull Ресурсы

Alexey Chubar
Во-вторых из-за неоптимального использования игровых ресурсов таких как 3D-модели текстуры анимации звуки и прочее

Импорт ресурсов

Alexey Chubar
Начнём с того что попроще - с игровых ресурсов Чтобы импортировать ресурс в проект Unity достаточно просто положить его в папку с проектом На слайде скриншот с их сайта И это действительно круто Однако настройки импорта по умолчанию зачастую не оптимальны особенно для мобильного приложения

Импорт ресурсов звук

Alexey Chubar
Это легко показать на примере звуков Вы кидаете MP3-мелодию в проект включаете её проигрывание на сцене всё работает Однако однажды мы вдруг обнаружили что звуки на уровне в игре занимают целых 30 МБ Притом что озвучка в принципе скромная звуки ударов и умений пара вскриков музыкальная тема и эмбиент

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 5: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Unity3D

Alexey Chubar
Соответственно игровой уровень в нашем случае представляет собой последовательность таких вот арен на которых игрока атакуют волны врагов злые боссы или персонажи других игроков
>

Unity3D

9 FPSШМЯК БРЯК

И В ПРОДАКШН

Alexey Chubar
Видно что уровень абстракии при таком подходе весьма высок Многое настраивается в визуальном редакторе количество низкоуровневого кода который разработчик пропускает через себя минимально В таких условиях важно не забывать как оно всё работает внутри Иначе легко сделать так что даже простые приложения будут тормозить на устройтстве у пользователя Более того некоторые действия на уровне Unity во время разработки могут иметь неожиданные и неочевидные последствия для производительности конечного продукта В данном докладе речь пойдёт о том что важно держать в голове во время разработки чтобы приложение в итоге не тормозило Помимо общих рекомендаций я поведаю о весьма неожиданных граблях на которые мы успели наступить во время разработки Гильдии Героев

Unity3D

PC amp Console games Mobile games

Architectural visualizations

Medical simulations

Military simulations

CAD

Research

Interactive presentations

hellip

Education

Media amp movies

Art installations

Alexey Chubar
Даже если вы не занимаетесь разработкой игр доклад вполне может быть полезен поскольку Unity применяется в большом количестве сфер деятельности

Unity3D

PC amp Console games Mobile games

Architectural visualizations

Medical simulations

Military simulations

CAD

Research

Interactive presentations

hellip

Education

Media amp movies

Art installations

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

Суровый мир мобильных игр

Alexey Chubar
Чем же он суров

Суровый мир мобильных игрbull Высокая конкуренция

Alexey Chubar
Благодаря вещам вроде Unity порог вхождения в индустрию весьма низок Рынок пресыщен На каждую игру можно найти 10 аналогов Чтобы игра была прибыльна она должна быть как мининум не хуже остальных И как бы она ни была хороша во всем остальном она должна быстро и стабильно работать иначе пользователь мгновенно уйдёт играть в игры конкурентов

Суровый мир мобильных игрbull Высокая конкуренцияbull Специфика аудитории

Alexey Chubar
Заметная часть пользователей (особенно на Google Play) любит купить китайский планшет за 3 тыщи рублей и потом винить разработчиков игр в том что у них всё тормозит (даже если игра выдаёт больше кадров в секунду чем главное меню их аппарата) Многие из покупателей бюджетных устройств конечно сознательны и понимают что дело в их устройстве и не пишут негативных отзывов на игру Но остальные не упустят возможности поставить 1 звёздочку В обоих случаях вы теряете пользователя Однако во втором случае вы теряете вдобавок ещё и будущих потенциальных пользователей которые зайдя на страницу игры видят негатив и предпочитают вашу игру не качать
Alexey Chubar
Поэтому надо сделать так чтобы у обладателей топовых устройств было красиво и быстро у обладателей бюджетных - хотя бы играбельно При этом в большинстве своём аудитория казуальная поэтому сделать огромное меню настройки графики как в ПК-играх - не вариант

Суровый мир мобильных игрbull Высокая конкуренцияbull Специфика аудиторииbull Специфика программно-аппаратной платформы

Alexey Chubar
Вдобавок программно-аппаратная начинка мобильных устройств имеет ряд важных отличий от консолей и ПК О них нужно сказать поподробнее чтобы понять с чем мы вообще имеем дело Android- и iOS-устройства несмотря на все свои различия разделяют часть важных с точки зрения разработки принципов

Что там внутриbull Какой-то странный процессорbull ARM x86 MIPShellip 32 и 64 bit

Alexey Chubar
Начнём с аппаратной начинки Современные флагманские устройства имееют поистине впечатляющие характеристики Много ядер много гигагерцев много гигабайт оперативки и так далее Однако когда мы слышим что выходит очередной смартфон с 8-ядерным процессором 25 ГГц мы конечно понимаем что это мягко говоря не то же самое что 8-ядерный Core i7

bull Какой-то странный процессорbull ARM x86 MIPShellip 32 и 64 bit

Что там внутри

ne

Alexey Chubar
Большинство устройств основаны на микроархитектуре ARMv7 которая значительно отличается от x86 Изначально это RISC-архитектура поэтому некоторые алгоритмы с которыми настольный компьютер справляется легко благодаря куче инструкций на все случаи жизни и SIMD-расширениями могут работать на ARM-процессоре куда медленнее

Что там внутриbull Какая-то батарейка

Alexey Chubar
Причина различий в производительности с настольными системами конечно понятна - это необходимость компактого размера и скромного энергопотребления Однако высокая нагрузка на процессор и интенсивный обмен данными по сети всё равно быстро посадят любой аккумулятор Если ваша игра будет разряжать телефон за час никто вас любить не будет Включая Google и Apple которые всё жестче следят за энергопотреблением приложений Поэтому следует оптимизировать игру минимизируя нагрузку на ЦП и обмен данными

Что там внутриbull Какой-то графический ускоритель

ne

Alexey Chubar
Да в телефонах есть что-то вроде видеокарты Но опять же это не совсем 250-ваттный GeForce Графические ускорители в мобильных устройствах имееют ряд особенностей которые важно понимать для достижения высокой производительности О них я подробнее расскажу ниже

Что там внутриbull Какая-то оперативная памятьbull Её всегда мало

Alexey Chubar
Одна из таких особенностей - отсутствие собственной видеопамяти Для своих нужд графический процессор использует часть оперативной памяти устройства И это дополнительно осложняет жизнь разработчику потому что оперативной памяти вечно не хватает Не хватает её в частности из-за специфики мобильных ОС Даже если ты работаешь с флагманом у которого 3-4 гигабайта оперативки это не значит что твоё приложение может выжрать все эти 3 гига Мобильная ОС не церемонится с приложениями которые потребляют много памяти Она завершает их работу как только ей понадобится память для других задач Если приложение наглеет система может втихую прибить его даже если оно сейчас открыто и пользователь на него смотрит Однако ещё до этого с ростом потребления памяти производительность приложения будет падать так как ему будет всё сложнее найти свободный участок памяти для каких-либо сиюминутных вычислений и операций Поэтому нужно очень аккуратно работать с оперативной памятью

Зоопарк устройств

Alexey Chubar
Я не случайно говорил какой-токакая-то на предыдущих слайдах Аппаратных конфигураций в итоге получается очень много На рынке находится целый зоопарк устройств И чтобы завладеть максимальной аудиторией болшинство устрйоств нужно поддерживать Считалось что фрагментация - удел Android однако сейчас и у Apple накопилось значительное число устровйств на базе iOS При этом вопреки стереотипам далеко не все обладатели айфонов и айпадов каждый год меняют свой девайс на новый Многие играют на iPad 2 и iPad Mini 1st Gen где всего 512 МБ ОЗУ

Зоопарк устройств

240 MB ought to be enough for anyone ndash Gill Bates

Alexey Chubar
Эмпирически мы выявили лимит потребления памяти игрой позволяющий её работать на устройствах с 512 Мб ОЗУ - примерно 240 МБ памяти Сюда соответственно входит и динамическая память приложения и текстуры и звук и проч Это довольно жесткое ограничение которое легко нарушить

bull Падение FPSbull Чёрные квадраты вместо текстурbull laquoТихоеraquo завершение приложения без отчёта об ошибке

Зоопарк устройств

gt240 MB

Alexey Chubar
При привышении этого лимита на слабых девайсах наблюдаются неприятные эффекты

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Alexey Chubar
В таких суровых условиях на ум приходит одна общая рекомендация которая уже сформулирована в документации Unity

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Постоянно спрашивай себя ldquoА не ерунду ли я сейчас делаюrdquo- Примерный перевод

Alexey Chubar
В голове нужно постоянно держать возможные последствия своих действий для производительности игры на мобильном устройстве И разрабатывать игру сразу с учётом жестких требований Рассмотрим же какие конкретные аспекты игры влияют на производительность

Из-за чего всё тормозит

Alexey Chubar
Что же в нашей игре нагружает процессор жрёт память и мучает видеокарту Из-за чего приложение работает не так быстро как хотелось бы Причины вполне ожидаемые

Из-за чего всё тормозитbull Код

Alexey Chubar
Во-первых из-за того как написан вами программный код При этом здесь я не говорю о том что криво написанный код работает медленно Это и так понятно В случае с Unity порой прямо написанный код работает медленно И его приходится переписывать более криво

Из-за чего всё тормозитbull Код bull Ресурсы

Alexey Chubar
Во-вторых из-за неоптимального использования игровых ресурсов таких как 3D-модели текстуры анимации звуки и прочее

Импорт ресурсов

Alexey Chubar
Начнём с того что попроще - с игровых ресурсов Чтобы импортировать ресурс в проект Unity достаточно просто положить его в папку с проектом На слайде скриншот с их сайта И это действительно круто Однако настройки импорта по умолчанию зачастую не оптимальны особенно для мобильного приложения

Импорт ресурсов звук

Alexey Chubar
Это легко показать на примере звуков Вы кидаете MP3-мелодию в проект включаете её проигрывание на сцене всё работает Однако однажды мы вдруг обнаружили что звуки на уровне в игре занимают целых 30 МБ Притом что озвучка в принципе скромная звуки ударов и умений пара вскриков музыкальная тема и эмбиент

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 6: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Unity3D

9 FPSШМЯК БРЯК

И В ПРОДАКШН

Alexey Chubar
Видно что уровень абстракии при таком подходе весьма высок Многое настраивается в визуальном редакторе количество низкоуровневого кода который разработчик пропускает через себя минимально В таких условиях важно не забывать как оно всё работает внутри Иначе легко сделать так что даже простые приложения будут тормозить на устройтстве у пользователя Более того некоторые действия на уровне Unity во время разработки могут иметь неожиданные и неочевидные последствия для производительности конечного продукта В данном докладе речь пойдёт о том что важно держать в голове во время разработки чтобы приложение в итоге не тормозило Помимо общих рекомендаций я поведаю о весьма неожиданных граблях на которые мы успели наступить во время разработки Гильдии Героев

Unity3D

PC amp Console games Mobile games

Architectural visualizations

Medical simulations

Military simulations

CAD

Research

Interactive presentations

hellip

Education

Media amp movies

Art installations

Alexey Chubar
Даже если вы не занимаетесь разработкой игр доклад вполне может быть полезен поскольку Unity применяется в большом количестве сфер деятельности

Unity3D

PC amp Console games Mobile games

Architectural visualizations

Medical simulations

Military simulations

CAD

Research

Interactive presentations

hellip

Education

Media amp movies

Art installations

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

Суровый мир мобильных игр

Alexey Chubar
Чем же он суров

Суровый мир мобильных игрbull Высокая конкуренция

Alexey Chubar
Благодаря вещам вроде Unity порог вхождения в индустрию весьма низок Рынок пресыщен На каждую игру можно найти 10 аналогов Чтобы игра была прибыльна она должна быть как мининум не хуже остальных И как бы она ни была хороша во всем остальном она должна быстро и стабильно работать иначе пользователь мгновенно уйдёт играть в игры конкурентов

Суровый мир мобильных игрbull Высокая конкуренцияbull Специфика аудитории

Alexey Chubar
Заметная часть пользователей (особенно на Google Play) любит купить китайский планшет за 3 тыщи рублей и потом винить разработчиков игр в том что у них всё тормозит (даже если игра выдаёт больше кадров в секунду чем главное меню их аппарата) Многие из покупателей бюджетных устройств конечно сознательны и понимают что дело в их устройстве и не пишут негативных отзывов на игру Но остальные не упустят возможности поставить 1 звёздочку В обоих случаях вы теряете пользователя Однако во втором случае вы теряете вдобавок ещё и будущих потенциальных пользователей которые зайдя на страницу игры видят негатив и предпочитают вашу игру не качать
Alexey Chubar
Поэтому надо сделать так чтобы у обладателей топовых устройств было красиво и быстро у обладателей бюджетных - хотя бы играбельно При этом в большинстве своём аудитория казуальная поэтому сделать огромное меню настройки графики как в ПК-играх - не вариант

Суровый мир мобильных игрbull Высокая конкуренцияbull Специфика аудиторииbull Специфика программно-аппаратной платформы

Alexey Chubar
Вдобавок программно-аппаратная начинка мобильных устройств имеет ряд важных отличий от консолей и ПК О них нужно сказать поподробнее чтобы понять с чем мы вообще имеем дело Android- и iOS-устройства несмотря на все свои различия разделяют часть важных с точки зрения разработки принципов

Что там внутриbull Какой-то странный процессорbull ARM x86 MIPShellip 32 и 64 bit

Alexey Chubar
Начнём с аппаратной начинки Современные флагманские устройства имееют поистине впечатляющие характеристики Много ядер много гигагерцев много гигабайт оперативки и так далее Однако когда мы слышим что выходит очередной смартфон с 8-ядерным процессором 25 ГГц мы конечно понимаем что это мягко говоря не то же самое что 8-ядерный Core i7

bull Какой-то странный процессорbull ARM x86 MIPShellip 32 и 64 bit

Что там внутри

ne

Alexey Chubar
Большинство устройств основаны на микроархитектуре ARMv7 которая значительно отличается от x86 Изначально это RISC-архитектура поэтому некоторые алгоритмы с которыми настольный компьютер справляется легко благодаря куче инструкций на все случаи жизни и SIMD-расширениями могут работать на ARM-процессоре куда медленнее

Что там внутриbull Какая-то батарейка

Alexey Chubar
Причина различий в производительности с настольными системами конечно понятна - это необходимость компактого размера и скромного энергопотребления Однако высокая нагрузка на процессор и интенсивный обмен данными по сети всё равно быстро посадят любой аккумулятор Если ваша игра будет разряжать телефон за час никто вас любить не будет Включая Google и Apple которые всё жестче следят за энергопотреблением приложений Поэтому следует оптимизировать игру минимизируя нагрузку на ЦП и обмен данными

Что там внутриbull Какой-то графический ускоритель

ne

Alexey Chubar
Да в телефонах есть что-то вроде видеокарты Но опять же это не совсем 250-ваттный GeForce Графические ускорители в мобильных устройствах имееют ряд особенностей которые важно понимать для достижения высокой производительности О них я подробнее расскажу ниже

Что там внутриbull Какая-то оперативная памятьbull Её всегда мало

Alexey Chubar
Одна из таких особенностей - отсутствие собственной видеопамяти Для своих нужд графический процессор использует часть оперативной памяти устройства И это дополнительно осложняет жизнь разработчику потому что оперативной памяти вечно не хватает Не хватает её в частности из-за специфики мобильных ОС Даже если ты работаешь с флагманом у которого 3-4 гигабайта оперативки это не значит что твоё приложение может выжрать все эти 3 гига Мобильная ОС не церемонится с приложениями которые потребляют много памяти Она завершает их работу как только ей понадобится память для других задач Если приложение наглеет система может втихую прибить его даже если оно сейчас открыто и пользователь на него смотрит Однако ещё до этого с ростом потребления памяти производительность приложения будет падать так как ему будет всё сложнее найти свободный участок памяти для каких-либо сиюминутных вычислений и операций Поэтому нужно очень аккуратно работать с оперативной памятью

Зоопарк устройств

Alexey Chubar
Я не случайно говорил какой-токакая-то на предыдущих слайдах Аппаратных конфигураций в итоге получается очень много На рынке находится целый зоопарк устройств И чтобы завладеть максимальной аудиторией болшинство устрйоств нужно поддерживать Считалось что фрагментация - удел Android однако сейчас и у Apple накопилось значительное число устровйств на базе iOS При этом вопреки стереотипам далеко не все обладатели айфонов и айпадов каждый год меняют свой девайс на новый Многие играют на iPad 2 и iPad Mini 1st Gen где всего 512 МБ ОЗУ

Зоопарк устройств

240 MB ought to be enough for anyone ndash Gill Bates

Alexey Chubar
Эмпирически мы выявили лимит потребления памяти игрой позволяющий её работать на устройствах с 512 Мб ОЗУ - примерно 240 МБ памяти Сюда соответственно входит и динамическая память приложения и текстуры и звук и проч Это довольно жесткое ограничение которое легко нарушить

bull Падение FPSbull Чёрные квадраты вместо текстурbull laquoТихоеraquo завершение приложения без отчёта об ошибке

Зоопарк устройств

gt240 MB

Alexey Chubar
При привышении этого лимита на слабых девайсах наблюдаются неприятные эффекты

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Alexey Chubar
В таких суровых условиях на ум приходит одна общая рекомендация которая уже сформулирована в документации Unity

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Постоянно спрашивай себя ldquoА не ерунду ли я сейчас делаюrdquo- Примерный перевод

Alexey Chubar
В голове нужно постоянно держать возможные последствия своих действий для производительности игры на мобильном устройстве И разрабатывать игру сразу с учётом жестких требований Рассмотрим же какие конкретные аспекты игры влияют на производительность

Из-за чего всё тормозит

Alexey Chubar
Что же в нашей игре нагружает процессор жрёт память и мучает видеокарту Из-за чего приложение работает не так быстро как хотелось бы Причины вполне ожидаемые

Из-за чего всё тормозитbull Код

Alexey Chubar
Во-первых из-за того как написан вами программный код При этом здесь я не говорю о том что криво написанный код работает медленно Это и так понятно В случае с Unity порой прямо написанный код работает медленно И его приходится переписывать более криво

Из-за чего всё тормозитbull Код bull Ресурсы

Alexey Chubar
Во-вторых из-за неоптимального использования игровых ресурсов таких как 3D-модели текстуры анимации звуки и прочее

Импорт ресурсов

Alexey Chubar
Начнём с того что попроще - с игровых ресурсов Чтобы импортировать ресурс в проект Unity достаточно просто положить его в папку с проектом На слайде скриншот с их сайта И это действительно круто Однако настройки импорта по умолчанию зачастую не оптимальны особенно для мобильного приложения

Импорт ресурсов звук

Alexey Chubar
Это легко показать на примере звуков Вы кидаете MP3-мелодию в проект включаете её проигрывание на сцене всё работает Однако однажды мы вдруг обнаружили что звуки на уровне в игре занимают целых 30 МБ Притом что озвучка в принципе скромная звуки ударов и умений пара вскриков музыкальная тема и эмбиент

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 7: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Unity3D

PC amp Console games Mobile games

Architectural visualizations

Medical simulations

Military simulations

CAD

Research

Interactive presentations

hellip

Education

Media amp movies

Art installations

Alexey Chubar
Даже если вы не занимаетесь разработкой игр доклад вполне может быть полезен поскольку Unity применяется в большом количестве сфер деятельности

Unity3D

PC amp Console games Mobile games

Architectural visualizations

Medical simulations

Military simulations

CAD

Research

Interactive presentations

hellip

Education

Media amp movies

Art installations

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

Суровый мир мобильных игр

Alexey Chubar
Чем же он суров

Суровый мир мобильных игрbull Высокая конкуренция

Alexey Chubar
Благодаря вещам вроде Unity порог вхождения в индустрию весьма низок Рынок пресыщен На каждую игру можно найти 10 аналогов Чтобы игра была прибыльна она должна быть как мининум не хуже остальных И как бы она ни была хороша во всем остальном она должна быстро и стабильно работать иначе пользователь мгновенно уйдёт играть в игры конкурентов

Суровый мир мобильных игрbull Высокая конкуренцияbull Специфика аудитории

Alexey Chubar
Заметная часть пользователей (особенно на Google Play) любит купить китайский планшет за 3 тыщи рублей и потом винить разработчиков игр в том что у них всё тормозит (даже если игра выдаёт больше кадров в секунду чем главное меню их аппарата) Многие из покупателей бюджетных устройств конечно сознательны и понимают что дело в их устройстве и не пишут негативных отзывов на игру Но остальные не упустят возможности поставить 1 звёздочку В обоих случаях вы теряете пользователя Однако во втором случае вы теряете вдобавок ещё и будущих потенциальных пользователей которые зайдя на страницу игры видят негатив и предпочитают вашу игру не качать
Alexey Chubar
Поэтому надо сделать так чтобы у обладателей топовых устройств было красиво и быстро у обладателей бюджетных - хотя бы играбельно При этом в большинстве своём аудитория казуальная поэтому сделать огромное меню настройки графики как в ПК-играх - не вариант

Суровый мир мобильных игрbull Высокая конкуренцияbull Специфика аудиторииbull Специфика программно-аппаратной платформы

Alexey Chubar
Вдобавок программно-аппаратная начинка мобильных устройств имеет ряд важных отличий от консолей и ПК О них нужно сказать поподробнее чтобы понять с чем мы вообще имеем дело Android- и iOS-устройства несмотря на все свои различия разделяют часть важных с точки зрения разработки принципов

Что там внутриbull Какой-то странный процессорbull ARM x86 MIPShellip 32 и 64 bit

Alexey Chubar
Начнём с аппаратной начинки Современные флагманские устройства имееют поистине впечатляющие характеристики Много ядер много гигагерцев много гигабайт оперативки и так далее Однако когда мы слышим что выходит очередной смартфон с 8-ядерным процессором 25 ГГц мы конечно понимаем что это мягко говоря не то же самое что 8-ядерный Core i7

bull Какой-то странный процессорbull ARM x86 MIPShellip 32 и 64 bit

Что там внутри

ne

Alexey Chubar
Большинство устройств основаны на микроархитектуре ARMv7 которая значительно отличается от x86 Изначально это RISC-архитектура поэтому некоторые алгоритмы с которыми настольный компьютер справляется легко благодаря куче инструкций на все случаи жизни и SIMD-расширениями могут работать на ARM-процессоре куда медленнее

Что там внутриbull Какая-то батарейка

Alexey Chubar
Причина различий в производительности с настольными системами конечно понятна - это необходимость компактого размера и скромного энергопотребления Однако высокая нагрузка на процессор и интенсивный обмен данными по сети всё равно быстро посадят любой аккумулятор Если ваша игра будет разряжать телефон за час никто вас любить не будет Включая Google и Apple которые всё жестче следят за энергопотреблением приложений Поэтому следует оптимизировать игру минимизируя нагрузку на ЦП и обмен данными

Что там внутриbull Какой-то графический ускоритель

ne

Alexey Chubar
Да в телефонах есть что-то вроде видеокарты Но опять же это не совсем 250-ваттный GeForce Графические ускорители в мобильных устройствах имееют ряд особенностей которые важно понимать для достижения высокой производительности О них я подробнее расскажу ниже

Что там внутриbull Какая-то оперативная памятьbull Её всегда мало

Alexey Chubar
Одна из таких особенностей - отсутствие собственной видеопамяти Для своих нужд графический процессор использует часть оперативной памяти устройства И это дополнительно осложняет жизнь разработчику потому что оперативной памяти вечно не хватает Не хватает её в частности из-за специфики мобильных ОС Даже если ты работаешь с флагманом у которого 3-4 гигабайта оперативки это не значит что твоё приложение может выжрать все эти 3 гига Мобильная ОС не церемонится с приложениями которые потребляют много памяти Она завершает их работу как только ей понадобится память для других задач Если приложение наглеет система может втихую прибить его даже если оно сейчас открыто и пользователь на него смотрит Однако ещё до этого с ростом потребления памяти производительность приложения будет падать так как ему будет всё сложнее найти свободный участок памяти для каких-либо сиюминутных вычислений и операций Поэтому нужно очень аккуратно работать с оперативной памятью

Зоопарк устройств

Alexey Chubar
Я не случайно говорил какой-токакая-то на предыдущих слайдах Аппаратных конфигураций в итоге получается очень много На рынке находится целый зоопарк устройств И чтобы завладеть максимальной аудиторией болшинство устрйоств нужно поддерживать Считалось что фрагментация - удел Android однако сейчас и у Apple накопилось значительное число устровйств на базе iOS При этом вопреки стереотипам далеко не все обладатели айфонов и айпадов каждый год меняют свой девайс на новый Многие играют на iPad 2 и iPad Mini 1st Gen где всего 512 МБ ОЗУ

Зоопарк устройств

240 MB ought to be enough for anyone ndash Gill Bates

Alexey Chubar
Эмпирически мы выявили лимит потребления памяти игрой позволяющий её работать на устройствах с 512 Мб ОЗУ - примерно 240 МБ памяти Сюда соответственно входит и динамическая память приложения и текстуры и звук и проч Это довольно жесткое ограничение которое легко нарушить

bull Падение FPSbull Чёрные квадраты вместо текстурbull laquoТихоеraquo завершение приложения без отчёта об ошибке

Зоопарк устройств

gt240 MB

Alexey Chubar
При привышении этого лимита на слабых девайсах наблюдаются неприятные эффекты

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Alexey Chubar
В таких суровых условиях на ум приходит одна общая рекомендация которая уже сформулирована в документации Unity

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Постоянно спрашивай себя ldquoА не ерунду ли я сейчас делаюrdquo- Примерный перевод

Alexey Chubar
В голове нужно постоянно держать возможные последствия своих действий для производительности игры на мобильном устройстве И разрабатывать игру сразу с учётом жестких требований Рассмотрим же какие конкретные аспекты игры влияют на производительность

Из-за чего всё тормозит

Alexey Chubar
Что же в нашей игре нагружает процессор жрёт память и мучает видеокарту Из-за чего приложение работает не так быстро как хотелось бы Причины вполне ожидаемые

Из-за чего всё тормозитbull Код

Alexey Chubar
Во-первых из-за того как написан вами программный код При этом здесь я не говорю о том что криво написанный код работает медленно Это и так понятно В случае с Unity порой прямо написанный код работает медленно И его приходится переписывать более криво

Из-за чего всё тормозитbull Код bull Ресурсы

Alexey Chubar
Во-вторых из-за неоптимального использования игровых ресурсов таких как 3D-модели текстуры анимации звуки и прочее

Импорт ресурсов

Alexey Chubar
Начнём с того что попроще - с игровых ресурсов Чтобы импортировать ресурс в проект Unity достаточно просто положить его в папку с проектом На слайде скриншот с их сайта И это действительно круто Однако настройки импорта по умолчанию зачастую не оптимальны особенно для мобильного приложения

Импорт ресурсов звук

Alexey Chubar
Это легко показать на примере звуков Вы кидаете MP3-мелодию в проект включаете её проигрывание на сцене всё работает Однако однажды мы вдруг обнаружили что звуки на уровне в игре занимают целых 30 МБ Притом что озвучка в принципе скромная звуки ударов и умений пара вскриков музыкальная тема и эмбиент

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 8: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Unity3D

PC amp Console games Mobile games

Architectural visualizations

Medical simulations

Military simulations

CAD

Research

Interactive presentations

hellip

Education

Media amp movies

Art installations

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

Суровый мир мобильных игр

Alexey Chubar
Чем же он суров

Суровый мир мобильных игрbull Высокая конкуренция

Alexey Chubar
Благодаря вещам вроде Unity порог вхождения в индустрию весьма низок Рынок пресыщен На каждую игру можно найти 10 аналогов Чтобы игра была прибыльна она должна быть как мининум не хуже остальных И как бы она ни была хороша во всем остальном она должна быстро и стабильно работать иначе пользователь мгновенно уйдёт играть в игры конкурентов

Суровый мир мобильных игрbull Высокая конкуренцияbull Специфика аудитории

Alexey Chubar
Заметная часть пользователей (особенно на Google Play) любит купить китайский планшет за 3 тыщи рублей и потом винить разработчиков игр в том что у них всё тормозит (даже если игра выдаёт больше кадров в секунду чем главное меню их аппарата) Многие из покупателей бюджетных устройств конечно сознательны и понимают что дело в их устройстве и не пишут негативных отзывов на игру Но остальные не упустят возможности поставить 1 звёздочку В обоих случаях вы теряете пользователя Однако во втором случае вы теряете вдобавок ещё и будущих потенциальных пользователей которые зайдя на страницу игры видят негатив и предпочитают вашу игру не качать
Alexey Chubar
Поэтому надо сделать так чтобы у обладателей топовых устройств было красиво и быстро у обладателей бюджетных - хотя бы играбельно При этом в большинстве своём аудитория казуальная поэтому сделать огромное меню настройки графики как в ПК-играх - не вариант

Суровый мир мобильных игрbull Высокая конкуренцияbull Специфика аудиторииbull Специфика программно-аппаратной платформы

Alexey Chubar
Вдобавок программно-аппаратная начинка мобильных устройств имеет ряд важных отличий от консолей и ПК О них нужно сказать поподробнее чтобы понять с чем мы вообще имеем дело Android- и iOS-устройства несмотря на все свои различия разделяют часть важных с точки зрения разработки принципов

Что там внутриbull Какой-то странный процессорbull ARM x86 MIPShellip 32 и 64 bit

Alexey Chubar
Начнём с аппаратной начинки Современные флагманские устройства имееют поистине впечатляющие характеристики Много ядер много гигагерцев много гигабайт оперативки и так далее Однако когда мы слышим что выходит очередной смартфон с 8-ядерным процессором 25 ГГц мы конечно понимаем что это мягко говоря не то же самое что 8-ядерный Core i7

bull Какой-то странный процессорbull ARM x86 MIPShellip 32 и 64 bit

Что там внутри

ne

Alexey Chubar
Большинство устройств основаны на микроархитектуре ARMv7 которая значительно отличается от x86 Изначально это RISC-архитектура поэтому некоторые алгоритмы с которыми настольный компьютер справляется легко благодаря куче инструкций на все случаи жизни и SIMD-расширениями могут работать на ARM-процессоре куда медленнее

Что там внутриbull Какая-то батарейка

Alexey Chubar
Причина различий в производительности с настольными системами конечно понятна - это необходимость компактого размера и скромного энергопотребления Однако высокая нагрузка на процессор и интенсивный обмен данными по сети всё равно быстро посадят любой аккумулятор Если ваша игра будет разряжать телефон за час никто вас любить не будет Включая Google и Apple которые всё жестче следят за энергопотреблением приложений Поэтому следует оптимизировать игру минимизируя нагрузку на ЦП и обмен данными

Что там внутриbull Какой-то графический ускоритель

ne

Alexey Chubar
Да в телефонах есть что-то вроде видеокарты Но опять же это не совсем 250-ваттный GeForce Графические ускорители в мобильных устройствах имееют ряд особенностей которые важно понимать для достижения высокой производительности О них я подробнее расскажу ниже

Что там внутриbull Какая-то оперативная памятьbull Её всегда мало

Alexey Chubar
Одна из таких особенностей - отсутствие собственной видеопамяти Для своих нужд графический процессор использует часть оперативной памяти устройства И это дополнительно осложняет жизнь разработчику потому что оперативной памяти вечно не хватает Не хватает её в частности из-за специфики мобильных ОС Даже если ты работаешь с флагманом у которого 3-4 гигабайта оперативки это не значит что твоё приложение может выжрать все эти 3 гига Мобильная ОС не церемонится с приложениями которые потребляют много памяти Она завершает их работу как только ей понадобится память для других задач Если приложение наглеет система может втихую прибить его даже если оно сейчас открыто и пользователь на него смотрит Однако ещё до этого с ростом потребления памяти производительность приложения будет падать так как ему будет всё сложнее найти свободный участок памяти для каких-либо сиюминутных вычислений и операций Поэтому нужно очень аккуратно работать с оперативной памятью

Зоопарк устройств

Alexey Chubar
Я не случайно говорил какой-токакая-то на предыдущих слайдах Аппаратных конфигураций в итоге получается очень много На рынке находится целый зоопарк устройств И чтобы завладеть максимальной аудиторией болшинство устрйоств нужно поддерживать Считалось что фрагментация - удел Android однако сейчас и у Apple накопилось значительное число устровйств на базе iOS При этом вопреки стереотипам далеко не все обладатели айфонов и айпадов каждый год меняют свой девайс на новый Многие играют на iPad 2 и iPad Mini 1st Gen где всего 512 МБ ОЗУ

Зоопарк устройств

240 MB ought to be enough for anyone ndash Gill Bates

Alexey Chubar
Эмпирически мы выявили лимит потребления памяти игрой позволяющий её работать на устройствах с 512 Мб ОЗУ - примерно 240 МБ памяти Сюда соответственно входит и динамическая память приложения и текстуры и звук и проч Это довольно жесткое ограничение которое легко нарушить

bull Падение FPSbull Чёрные квадраты вместо текстурbull laquoТихоеraquo завершение приложения без отчёта об ошибке

Зоопарк устройств

gt240 MB

Alexey Chubar
При привышении этого лимита на слабых девайсах наблюдаются неприятные эффекты

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Alexey Chubar
В таких суровых условиях на ум приходит одна общая рекомендация которая уже сформулирована в документации Unity

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Постоянно спрашивай себя ldquoА не ерунду ли я сейчас делаюrdquo- Примерный перевод

Alexey Chubar
В голове нужно постоянно держать возможные последствия своих действий для производительности игры на мобильном устройстве И разрабатывать игру сразу с учётом жестких требований Рассмотрим же какие конкретные аспекты игры влияют на производительность

Из-за чего всё тормозит

Alexey Chubar
Что же в нашей игре нагружает процессор жрёт память и мучает видеокарту Из-за чего приложение работает не так быстро как хотелось бы Причины вполне ожидаемые

Из-за чего всё тормозитbull Код

Alexey Chubar
Во-первых из-за того как написан вами программный код При этом здесь я не говорю о том что криво написанный код работает медленно Это и так понятно В случае с Unity порой прямо написанный код работает медленно И его приходится переписывать более криво

Из-за чего всё тормозитbull Код bull Ресурсы

Alexey Chubar
Во-вторых из-за неоптимального использования игровых ресурсов таких как 3D-модели текстуры анимации звуки и прочее

Импорт ресурсов

Alexey Chubar
Начнём с того что попроще - с игровых ресурсов Чтобы импортировать ресурс в проект Unity достаточно просто положить его в папку с проектом На слайде скриншот с их сайта И это действительно круто Однако настройки импорта по умолчанию зачастую не оптимальны особенно для мобильного приложения

Импорт ресурсов звук

Alexey Chubar
Это легко показать на примере звуков Вы кидаете MP3-мелодию в проект включаете её проигрывание на сцене всё работает Однако однажды мы вдруг обнаружили что звуки на уровне в игре занимают целых 30 МБ Притом что озвучка в принципе скромная звуки ударов и умений пара вскриков музыкальная тема и эмбиент

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 9: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Суровый мир мобильных игр

Alexey Chubar
Чем же он суров

Суровый мир мобильных игрbull Высокая конкуренция

Alexey Chubar
Благодаря вещам вроде Unity порог вхождения в индустрию весьма низок Рынок пресыщен На каждую игру можно найти 10 аналогов Чтобы игра была прибыльна она должна быть как мининум не хуже остальных И как бы она ни была хороша во всем остальном она должна быстро и стабильно работать иначе пользователь мгновенно уйдёт играть в игры конкурентов

Суровый мир мобильных игрbull Высокая конкуренцияbull Специфика аудитории

Alexey Chubar
Заметная часть пользователей (особенно на Google Play) любит купить китайский планшет за 3 тыщи рублей и потом винить разработчиков игр в том что у них всё тормозит (даже если игра выдаёт больше кадров в секунду чем главное меню их аппарата) Многие из покупателей бюджетных устройств конечно сознательны и понимают что дело в их устройстве и не пишут негативных отзывов на игру Но остальные не упустят возможности поставить 1 звёздочку В обоих случаях вы теряете пользователя Однако во втором случае вы теряете вдобавок ещё и будущих потенциальных пользователей которые зайдя на страницу игры видят негатив и предпочитают вашу игру не качать
Alexey Chubar
Поэтому надо сделать так чтобы у обладателей топовых устройств было красиво и быстро у обладателей бюджетных - хотя бы играбельно При этом в большинстве своём аудитория казуальная поэтому сделать огромное меню настройки графики как в ПК-играх - не вариант

Суровый мир мобильных игрbull Высокая конкуренцияbull Специфика аудиторииbull Специфика программно-аппаратной платформы

Alexey Chubar
Вдобавок программно-аппаратная начинка мобильных устройств имеет ряд важных отличий от консолей и ПК О них нужно сказать поподробнее чтобы понять с чем мы вообще имеем дело Android- и iOS-устройства несмотря на все свои различия разделяют часть важных с точки зрения разработки принципов

Что там внутриbull Какой-то странный процессорbull ARM x86 MIPShellip 32 и 64 bit

Alexey Chubar
Начнём с аппаратной начинки Современные флагманские устройства имееют поистине впечатляющие характеристики Много ядер много гигагерцев много гигабайт оперативки и так далее Однако когда мы слышим что выходит очередной смартфон с 8-ядерным процессором 25 ГГц мы конечно понимаем что это мягко говоря не то же самое что 8-ядерный Core i7

bull Какой-то странный процессорbull ARM x86 MIPShellip 32 и 64 bit

Что там внутри

ne

Alexey Chubar
Большинство устройств основаны на микроархитектуре ARMv7 которая значительно отличается от x86 Изначально это RISC-архитектура поэтому некоторые алгоритмы с которыми настольный компьютер справляется легко благодаря куче инструкций на все случаи жизни и SIMD-расширениями могут работать на ARM-процессоре куда медленнее

Что там внутриbull Какая-то батарейка

Alexey Chubar
Причина различий в производительности с настольными системами конечно понятна - это необходимость компактого размера и скромного энергопотребления Однако высокая нагрузка на процессор и интенсивный обмен данными по сети всё равно быстро посадят любой аккумулятор Если ваша игра будет разряжать телефон за час никто вас любить не будет Включая Google и Apple которые всё жестче следят за энергопотреблением приложений Поэтому следует оптимизировать игру минимизируя нагрузку на ЦП и обмен данными

Что там внутриbull Какой-то графический ускоритель

ne

Alexey Chubar
Да в телефонах есть что-то вроде видеокарты Но опять же это не совсем 250-ваттный GeForce Графические ускорители в мобильных устройствах имееют ряд особенностей которые важно понимать для достижения высокой производительности О них я подробнее расскажу ниже

Что там внутриbull Какая-то оперативная памятьbull Её всегда мало

Alexey Chubar
Одна из таких особенностей - отсутствие собственной видеопамяти Для своих нужд графический процессор использует часть оперативной памяти устройства И это дополнительно осложняет жизнь разработчику потому что оперативной памяти вечно не хватает Не хватает её в частности из-за специфики мобильных ОС Даже если ты работаешь с флагманом у которого 3-4 гигабайта оперативки это не значит что твоё приложение может выжрать все эти 3 гига Мобильная ОС не церемонится с приложениями которые потребляют много памяти Она завершает их работу как только ей понадобится память для других задач Если приложение наглеет система может втихую прибить его даже если оно сейчас открыто и пользователь на него смотрит Однако ещё до этого с ростом потребления памяти производительность приложения будет падать так как ему будет всё сложнее найти свободный участок памяти для каких-либо сиюминутных вычислений и операций Поэтому нужно очень аккуратно работать с оперативной памятью

Зоопарк устройств

Alexey Chubar
Я не случайно говорил какой-токакая-то на предыдущих слайдах Аппаратных конфигураций в итоге получается очень много На рынке находится целый зоопарк устройств И чтобы завладеть максимальной аудиторией болшинство устрйоств нужно поддерживать Считалось что фрагментация - удел Android однако сейчас и у Apple накопилось значительное число устровйств на базе iOS При этом вопреки стереотипам далеко не все обладатели айфонов и айпадов каждый год меняют свой девайс на новый Многие играют на iPad 2 и iPad Mini 1st Gen где всего 512 МБ ОЗУ

Зоопарк устройств

240 MB ought to be enough for anyone ndash Gill Bates

Alexey Chubar
Эмпирически мы выявили лимит потребления памяти игрой позволяющий её работать на устройствах с 512 Мб ОЗУ - примерно 240 МБ памяти Сюда соответственно входит и динамическая память приложения и текстуры и звук и проч Это довольно жесткое ограничение которое легко нарушить

bull Падение FPSbull Чёрные квадраты вместо текстурbull laquoТихоеraquo завершение приложения без отчёта об ошибке

Зоопарк устройств

gt240 MB

Alexey Chubar
При привышении этого лимита на слабых девайсах наблюдаются неприятные эффекты

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Alexey Chubar
В таких суровых условиях на ум приходит одна общая рекомендация которая уже сформулирована в документации Unity

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Постоянно спрашивай себя ldquoА не ерунду ли я сейчас делаюrdquo- Примерный перевод

Alexey Chubar
В голове нужно постоянно держать возможные последствия своих действий для производительности игры на мобильном устройстве И разрабатывать игру сразу с учётом жестких требований Рассмотрим же какие конкретные аспекты игры влияют на производительность

Из-за чего всё тормозит

Alexey Chubar
Что же в нашей игре нагружает процессор жрёт память и мучает видеокарту Из-за чего приложение работает не так быстро как хотелось бы Причины вполне ожидаемые

Из-за чего всё тормозитbull Код

Alexey Chubar
Во-первых из-за того как написан вами программный код При этом здесь я не говорю о том что криво написанный код работает медленно Это и так понятно В случае с Unity порой прямо написанный код работает медленно И его приходится переписывать более криво

Из-за чего всё тормозитbull Код bull Ресурсы

Alexey Chubar
Во-вторых из-за неоптимального использования игровых ресурсов таких как 3D-модели текстуры анимации звуки и прочее

Импорт ресурсов

Alexey Chubar
Начнём с того что попроще - с игровых ресурсов Чтобы импортировать ресурс в проект Unity достаточно просто положить его в папку с проектом На слайде скриншот с их сайта И это действительно круто Однако настройки импорта по умолчанию зачастую не оптимальны особенно для мобильного приложения

Импорт ресурсов звук

Alexey Chubar
Это легко показать на примере звуков Вы кидаете MP3-мелодию в проект включаете её проигрывание на сцене всё работает Однако однажды мы вдруг обнаружили что звуки на уровне в игре занимают целых 30 МБ Притом что озвучка в принципе скромная звуки ударов и умений пара вскриков музыкальная тема и эмбиент

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 10: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Суровый мир мобильных игрbull Высокая конкуренция

Alexey Chubar
Благодаря вещам вроде Unity порог вхождения в индустрию весьма низок Рынок пресыщен На каждую игру можно найти 10 аналогов Чтобы игра была прибыльна она должна быть как мининум не хуже остальных И как бы она ни была хороша во всем остальном она должна быстро и стабильно работать иначе пользователь мгновенно уйдёт играть в игры конкурентов

Суровый мир мобильных игрbull Высокая конкуренцияbull Специфика аудитории

Alexey Chubar
Заметная часть пользователей (особенно на Google Play) любит купить китайский планшет за 3 тыщи рублей и потом винить разработчиков игр в том что у них всё тормозит (даже если игра выдаёт больше кадров в секунду чем главное меню их аппарата) Многие из покупателей бюджетных устройств конечно сознательны и понимают что дело в их устройстве и не пишут негативных отзывов на игру Но остальные не упустят возможности поставить 1 звёздочку В обоих случаях вы теряете пользователя Однако во втором случае вы теряете вдобавок ещё и будущих потенциальных пользователей которые зайдя на страницу игры видят негатив и предпочитают вашу игру не качать
Alexey Chubar
Поэтому надо сделать так чтобы у обладателей топовых устройств было красиво и быстро у обладателей бюджетных - хотя бы играбельно При этом в большинстве своём аудитория казуальная поэтому сделать огромное меню настройки графики как в ПК-играх - не вариант

Суровый мир мобильных игрbull Высокая конкуренцияbull Специфика аудиторииbull Специфика программно-аппаратной платформы

Alexey Chubar
Вдобавок программно-аппаратная начинка мобильных устройств имеет ряд важных отличий от консолей и ПК О них нужно сказать поподробнее чтобы понять с чем мы вообще имеем дело Android- и iOS-устройства несмотря на все свои различия разделяют часть важных с точки зрения разработки принципов

Что там внутриbull Какой-то странный процессорbull ARM x86 MIPShellip 32 и 64 bit

Alexey Chubar
Начнём с аппаратной начинки Современные флагманские устройства имееют поистине впечатляющие характеристики Много ядер много гигагерцев много гигабайт оперативки и так далее Однако когда мы слышим что выходит очередной смартфон с 8-ядерным процессором 25 ГГц мы конечно понимаем что это мягко говоря не то же самое что 8-ядерный Core i7

bull Какой-то странный процессорbull ARM x86 MIPShellip 32 и 64 bit

Что там внутри

ne

Alexey Chubar
Большинство устройств основаны на микроархитектуре ARMv7 которая значительно отличается от x86 Изначально это RISC-архитектура поэтому некоторые алгоритмы с которыми настольный компьютер справляется легко благодаря куче инструкций на все случаи жизни и SIMD-расширениями могут работать на ARM-процессоре куда медленнее

Что там внутриbull Какая-то батарейка

Alexey Chubar
Причина различий в производительности с настольными системами конечно понятна - это необходимость компактого размера и скромного энергопотребления Однако высокая нагрузка на процессор и интенсивный обмен данными по сети всё равно быстро посадят любой аккумулятор Если ваша игра будет разряжать телефон за час никто вас любить не будет Включая Google и Apple которые всё жестче следят за энергопотреблением приложений Поэтому следует оптимизировать игру минимизируя нагрузку на ЦП и обмен данными

Что там внутриbull Какой-то графический ускоритель

ne

Alexey Chubar
Да в телефонах есть что-то вроде видеокарты Но опять же это не совсем 250-ваттный GeForce Графические ускорители в мобильных устройствах имееют ряд особенностей которые важно понимать для достижения высокой производительности О них я подробнее расскажу ниже

Что там внутриbull Какая-то оперативная памятьbull Её всегда мало

Alexey Chubar
Одна из таких особенностей - отсутствие собственной видеопамяти Для своих нужд графический процессор использует часть оперативной памяти устройства И это дополнительно осложняет жизнь разработчику потому что оперативной памяти вечно не хватает Не хватает её в частности из-за специфики мобильных ОС Даже если ты работаешь с флагманом у которого 3-4 гигабайта оперативки это не значит что твоё приложение может выжрать все эти 3 гига Мобильная ОС не церемонится с приложениями которые потребляют много памяти Она завершает их работу как только ей понадобится память для других задач Если приложение наглеет система может втихую прибить его даже если оно сейчас открыто и пользователь на него смотрит Однако ещё до этого с ростом потребления памяти производительность приложения будет падать так как ему будет всё сложнее найти свободный участок памяти для каких-либо сиюминутных вычислений и операций Поэтому нужно очень аккуратно работать с оперативной памятью

Зоопарк устройств

Alexey Chubar
Я не случайно говорил какой-токакая-то на предыдущих слайдах Аппаратных конфигураций в итоге получается очень много На рынке находится целый зоопарк устройств И чтобы завладеть максимальной аудиторией болшинство устрйоств нужно поддерживать Считалось что фрагментация - удел Android однако сейчас и у Apple накопилось значительное число устровйств на базе iOS При этом вопреки стереотипам далеко не все обладатели айфонов и айпадов каждый год меняют свой девайс на новый Многие играют на iPad 2 и iPad Mini 1st Gen где всего 512 МБ ОЗУ

Зоопарк устройств

240 MB ought to be enough for anyone ndash Gill Bates

Alexey Chubar
Эмпирически мы выявили лимит потребления памяти игрой позволяющий её работать на устройствах с 512 Мб ОЗУ - примерно 240 МБ памяти Сюда соответственно входит и динамическая память приложения и текстуры и звук и проч Это довольно жесткое ограничение которое легко нарушить

bull Падение FPSbull Чёрные квадраты вместо текстурbull laquoТихоеraquo завершение приложения без отчёта об ошибке

Зоопарк устройств

gt240 MB

Alexey Chubar
При привышении этого лимита на слабых девайсах наблюдаются неприятные эффекты

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Alexey Chubar
В таких суровых условиях на ум приходит одна общая рекомендация которая уже сформулирована в документации Unity

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Постоянно спрашивай себя ldquoА не ерунду ли я сейчас делаюrdquo- Примерный перевод

Alexey Chubar
В голове нужно постоянно держать возможные последствия своих действий для производительности игры на мобильном устройстве И разрабатывать игру сразу с учётом жестких требований Рассмотрим же какие конкретные аспекты игры влияют на производительность

Из-за чего всё тормозит

Alexey Chubar
Что же в нашей игре нагружает процессор жрёт память и мучает видеокарту Из-за чего приложение работает не так быстро как хотелось бы Причины вполне ожидаемые

Из-за чего всё тормозитbull Код

Alexey Chubar
Во-первых из-за того как написан вами программный код При этом здесь я не говорю о том что криво написанный код работает медленно Это и так понятно В случае с Unity порой прямо написанный код работает медленно И его приходится переписывать более криво

Из-за чего всё тормозитbull Код bull Ресурсы

Alexey Chubar
Во-вторых из-за неоптимального использования игровых ресурсов таких как 3D-модели текстуры анимации звуки и прочее

Импорт ресурсов

Alexey Chubar
Начнём с того что попроще - с игровых ресурсов Чтобы импортировать ресурс в проект Unity достаточно просто положить его в папку с проектом На слайде скриншот с их сайта И это действительно круто Однако настройки импорта по умолчанию зачастую не оптимальны особенно для мобильного приложения

Импорт ресурсов звук

Alexey Chubar
Это легко показать на примере звуков Вы кидаете MP3-мелодию в проект включаете её проигрывание на сцене всё работает Однако однажды мы вдруг обнаружили что звуки на уровне в игре занимают целых 30 МБ Притом что озвучка в принципе скромная звуки ударов и умений пара вскриков музыкальная тема и эмбиент

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 11: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Суровый мир мобильных игрbull Высокая конкуренцияbull Специфика аудитории

Alexey Chubar
Заметная часть пользователей (особенно на Google Play) любит купить китайский планшет за 3 тыщи рублей и потом винить разработчиков игр в том что у них всё тормозит (даже если игра выдаёт больше кадров в секунду чем главное меню их аппарата) Многие из покупателей бюджетных устройств конечно сознательны и понимают что дело в их устройстве и не пишут негативных отзывов на игру Но остальные не упустят возможности поставить 1 звёздочку В обоих случаях вы теряете пользователя Однако во втором случае вы теряете вдобавок ещё и будущих потенциальных пользователей которые зайдя на страницу игры видят негатив и предпочитают вашу игру не качать
Alexey Chubar
Поэтому надо сделать так чтобы у обладателей топовых устройств было красиво и быстро у обладателей бюджетных - хотя бы играбельно При этом в большинстве своём аудитория казуальная поэтому сделать огромное меню настройки графики как в ПК-играх - не вариант

Суровый мир мобильных игрbull Высокая конкуренцияbull Специфика аудиторииbull Специфика программно-аппаратной платформы

Alexey Chubar
Вдобавок программно-аппаратная начинка мобильных устройств имеет ряд важных отличий от консолей и ПК О них нужно сказать поподробнее чтобы понять с чем мы вообще имеем дело Android- и iOS-устройства несмотря на все свои различия разделяют часть важных с точки зрения разработки принципов

Что там внутриbull Какой-то странный процессорbull ARM x86 MIPShellip 32 и 64 bit

Alexey Chubar
Начнём с аппаратной начинки Современные флагманские устройства имееют поистине впечатляющие характеристики Много ядер много гигагерцев много гигабайт оперативки и так далее Однако когда мы слышим что выходит очередной смартфон с 8-ядерным процессором 25 ГГц мы конечно понимаем что это мягко говоря не то же самое что 8-ядерный Core i7

bull Какой-то странный процессорbull ARM x86 MIPShellip 32 и 64 bit

Что там внутри

ne

Alexey Chubar
Большинство устройств основаны на микроархитектуре ARMv7 которая значительно отличается от x86 Изначально это RISC-архитектура поэтому некоторые алгоритмы с которыми настольный компьютер справляется легко благодаря куче инструкций на все случаи жизни и SIMD-расширениями могут работать на ARM-процессоре куда медленнее

Что там внутриbull Какая-то батарейка

Alexey Chubar
Причина различий в производительности с настольными системами конечно понятна - это необходимость компактого размера и скромного энергопотребления Однако высокая нагрузка на процессор и интенсивный обмен данными по сети всё равно быстро посадят любой аккумулятор Если ваша игра будет разряжать телефон за час никто вас любить не будет Включая Google и Apple которые всё жестче следят за энергопотреблением приложений Поэтому следует оптимизировать игру минимизируя нагрузку на ЦП и обмен данными

Что там внутриbull Какой-то графический ускоритель

ne

Alexey Chubar
Да в телефонах есть что-то вроде видеокарты Но опять же это не совсем 250-ваттный GeForce Графические ускорители в мобильных устройствах имееют ряд особенностей которые важно понимать для достижения высокой производительности О них я подробнее расскажу ниже

Что там внутриbull Какая-то оперативная памятьbull Её всегда мало

Alexey Chubar
Одна из таких особенностей - отсутствие собственной видеопамяти Для своих нужд графический процессор использует часть оперативной памяти устройства И это дополнительно осложняет жизнь разработчику потому что оперативной памяти вечно не хватает Не хватает её в частности из-за специфики мобильных ОС Даже если ты работаешь с флагманом у которого 3-4 гигабайта оперативки это не значит что твоё приложение может выжрать все эти 3 гига Мобильная ОС не церемонится с приложениями которые потребляют много памяти Она завершает их работу как только ей понадобится память для других задач Если приложение наглеет система может втихую прибить его даже если оно сейчас открыто и пользователь на него смотрит Однако ещё до этого с ростом потребления памяти производительность приложения будет падать так как ему будет всё сложнее найти свободный участок памяти для каких-либо сиюминутных вычислений и операций Поэтому нужно очень аккуратно работать с оперативной памятью

Зоопарк устройств

Alexey Chubar
Я не случайно говорил какой-токакая-то на предыдущих слайдах Аппаратных конфигураций в итоге получается очень много На рынке находится целый зоопарк устройств И чтобы завладеть максимальной аудиторией болшинство устрйоств нужно поддерживать Считалось что фрагментация - удел Android однако сейчас и у Apple накопилось значительное число устровйств на базе iOS При этом вопреки стереотипам далеко не все обладатели айфонов и айпадов каждый год меняют свой девайс на новый Многие играют на iPad 2 и iPad Mini 1st Gen где всего 512 МБ ОЗУ

Зоопарк устройств

240 MB ought to be enough for anyone ndash Gill Bates

Alexey Chubar
Эмпирически мы выявили лимит потребления памяти игрой позволяющий её работать на устройствах с 512 Мб ОЗУ - примерно 240 МБ памяти Сюда соответственно входит и динамическая память приложения и текстуры и звук и проч Это довольно жесткое ограничение которое легко нарушить

bull Падение FPSbull Чёрные квадраты вместо текстурbull laquoТихоеraquo завершение приложения без отчёта об ошибке

Зоопарк устройств

gt240 MB

Alexey Chubar
При привышении этого лимита на слабых девайсах наблюдаются неприятные эффекты

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Alexey Chubar
В таких суровых условиях на ум приходит одна общая рекомендация которая уже сформулирована в документации Unity

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Постоянно спрашивай себя ldquoА не ерунду ли я сейчас делаюrdquo- Примерный перевод

Alexey Chubar
В голове нужно постоянно держать возможные последствия своих действий для производительности игры на мобильном устройстве И разрабатывать игру сразу с учётом жестких требований Рассмотрим же какие конкретные аспекты игры влияют на производительность

Из-за чего всё тормозит

Alexey Chubar
Что же в нашей игре нагружает процессор жрёт память и мучает видеокарту Из-за чего приложение работает не так быстро как хотелось бы Причины вполне ожидаемые

Из-за чего всё тормозитbull Код

Alexey Chubar
Во-первых из-за того как написан вами программный код При этом здесь я не говорю о том что криво написанный код работает медленно Это и так понятно В случае с Unity порой прямо написанный код работает медленно И его приходится переписывать более криво

Из-за чего всё тормозитbull Код bull Ресурсы

Alexey Chubar
Во-вторых из-за неоптимального использования игровых ресурсов таких как 3D-модели текстуры анимации звуки и прочее

Импорт ресурсов

Alexey Chubar
Начнём с того что попроще - с игровых ресурсов Чтобы импортировать ресурс в проект Unity достаточно просто положить его в папку с проектом На слайде скриншот с их сайта И это действительно круто Однако настройки импорта по умолчанию зачастую не оптимальны особенно для мобильного приложения

Импорт ресурсов звук

Alexey Chubar
Это легко показать на примере звуков Вы кидаете MP3-мелодию в проект включаете её проигрывание на сцене всё работает Однако однажды мы вдруг обнаружили что звуки на уровне в игре занимают целых 30 МБ Притом что озвучка в принципе скромная звуки ударов и умений пара вскриков музыкальная тема и эмбиент

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 12: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Суровый мир мобильных игрbull Высокая конкуренцияbull Специфика аудиторииbull Специфика программно-аппаратной платформы

Alexey Chubar
Вдобавок программно-аппаратная начинка мобильных устройств имеет ряд важных отличий от консолей и ПК О них нужно сказать поподробнее чтобы понять с чем мы вообще имеем дело Android- и iOS-устройства несмотря на все свои различия разделяют часть важных с точки зрения разработки принципов

Что там внутриbull Какой-то странный процессорbull ARM x86 MIPShellip 32 и 64 bit

Alexey Chubar
Начнём с аппаратной начинки Современные флагманские устройства имееют поистине впечатляющие характеристики Много ядер много гигагерцев много гигабайт оперативки и так далее Однако когда мы слышим что выходит очередной смартфон с 8-ядерным процессором 25 ГГц мы конечно понимаем что это мягко говоря не то же самое что 8-ядерный Core i7

bull Какой-то странный процессорbull ARM x86 MIPShellip 32 и 64 bit

Что там внутри

ne

Alexey Chubar
Большинство устройств основаны на микроархитектуре ARMv7 которая значительно отличается от x86 Изначально это RISC-архитектура поэтому некоторые алгоритмы с которыми настольный компьютер справляется легко благодаря куче инструкций на все случаи жизни и SIMD-расширениями могут работать на ARM-процессоре куда медленнее

Что там внутриbull Какая-то батарейка

Alexey Chubar
Причина различий в производительности с настольными системами конечно понятна - это необходимость компактого размера и скромного энергопотребления Однако высокая нагрузка на процессор и интенсивный обмен данными по сети всё равно быстро посадят любой аккумулятор Если ваша игра будет разряжать телефон за час никто вас любить не будет Включая Google и Apple которые всё жестче следят за энергопотреблением приложений Поэтому следует оптимизировать игру минимизируя нагрузку на ЦП и обмен данными

Что там внутриbull Какой-то графический ускоритель

ne

Alexey Chubar
Да в телефонах есть что-то вроде видеокарты Но опять же это не совсем 250-ваттный GeForce Графические ускорители в мобильных устройствах имееют ряд особенностей которые важно понимать для достижения высокой производительности О них я подробнее расскажу ниже

Что там внутриbull Какая-то оперативная памятьbull Её всегда мало

Alexey Chubar
Одна из таких особенностей - отсутствие собственной видеопамяти Для своих нужд графический процессор использует часть оперативной памяти устройства И это дополнительно осложняет жизнь разработчику потому что оперативной памяти вечно не хватает Не хватает её в частности из-за специфики мобильных ОС Даже если ты работаешь с флагманом у которого 3-4 гигабайта оперативки это не значит что твоё приложение может выжрать все эти 3 гига Мобильная ОС не церемонится с приложениями которые потребляют много памяти Она завершает их работу как только ей понадобится память для других задач Если приложение наглеет система может втихую прибить его даже если оно сейчас открыто и пользователь на него смотрит Однако ещё до этого с ростом потребления памяти производительность приложения будет падать так как ему будет всё сложнее найти свободный участок памяти для каких-либо сиюминутных вычислений и операций Поэтому нужно очень аккуратно работать с оперативной памятью

Зоопарк устройств

Alexey Chubar
Я не случайно говорил какой-токакая-то на предыдущих слайдах Аппаратных конфигураций в итоге получается очень много На рынке находится целый зоопарк устройств И чтобы завладеть максимальной аудиторией болшинство устрйоств нужно поддерживать Считалось что фрагментация - удел Android однако сейчас и у Apple накопилось значительное число устровйств на базе iOS При этом вопреки стереотипам далеко не все обладатели айфонов и айпадов каждый год меняют свой девайс на новый Многие играют на iPad 2 и iPad Mini 1st Gen где всего 512 МБ ОЗУ

Зоопарк устройств

240 MB ought to be enough for anyone ndash Gill Bates

Alexey Chubar
Эмпирически мы выявили лимит потребления памяти игрой позволяющий её работать на устройствах с 512 Мб ОЗУ - примерно 240 МБ памяти Сюда соответственно входит и динамическая память приложения и текстуры и звук и проч Это довольно жесткое ограничение которое легко нарушить

bull Падение FPSbull Чёрные квадраты вместо текстурbull laquoТихоеraquo завершение приложения без отчёта об ошибке

Зоопарк устройств

gt240 MB

Alexey Chubar
При привышении этого лимита на слабых девайсах наблюдаются неприятные эффекты

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Alexey Chubar
В таких суровых условиях на ум приходит одна общая рекомендация которая уже сформулирована в документации Unity

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Постоянно спрашивай себя ldquoА не ерунду ли я сейчас делаюrdquo- Примерный перевод

Alexey Chubar
В голове нужно постоянно держать возможные последствия своих действий для производительности игры на мобильном устройстве И разрабатывать игру сразу с учётом жестких требований Рассмотрим же какие конкретные аспекты игры влияют на производительность

Из-за чего всё тормозит

Alexey Chubar
Что же в нашей игре нагружает процессор жрёт память и мучает видеокарту Из-за чего приложение работает не так быстро как хотелось бы Причины вполне ожидаемые

Из-за чего всё тормозитbull Код

Alexey Chubar
Во-первых из-за того как написан вами программный код При этом здесь я не говорю о том что криво написанный код работает медленно Это и так понятно В случае с Unity порой прямо написанный код работает медленно И его приходится переписывать более криво

Из-за чего всё тормозитbull Код bull Ресурсы

Alexey Chubar
Во-вторых из-за неоптимального использования игровых ресурсов таких как 3D-модели текстуры анимации звуки и прочее

Импорт ресурсов

Alexey Chubar
Начнём с того что попроще - с игровых ресурсов Чтобы импортировать ресурс в проект Unity достаточно просто положить его в папку с проектом На слайде скриншот с их сайта И это действительно круто Однако настройки импорта по умолчанию зачастую не оптимальны особенно для мобильного приложения

Импорт ресурсов звук

Alexey Chubar
Это легко показать на примере звуков Вы кидаете MP3-мелодию в проект включаете её проигрывание на сцене всё работает Однако однажды мы вдруг обнаружили что звуки на уровне в игре занимают целых 30 МБ Притом что озвучка в принципе скромная звуки ударов и умений пара вскриков музыкальная тема и эмбиент

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 13: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Что там внутриbull Какой-то странный процессорbull ARM x86 MIPShellip 32 и 64 bit

Alexey Chubar
Начнём с аппаратной начинки Современные флагманские устройства имееют поистине впечатляющие характеристики Много ядер много гигагерцев много гигабайт оперативки и так далее Однако когда мы слышим что выходит очередной смартфон с 8-ядерным процессором 25 ГГц мы конечно понимаем что это мягко говоря не то же самое что 8-ядерный Core i7

bull Какой-то странный процессорbull ARM x86 MIPShellip 32 и 64 bit

Что там внутри

ne

Alexey Chubar
Большинство устройств основаны на микроархитектуре ARMv7 которая значительно отличается от x86 Изначально это RISC-архитектура поэтому некоторые алгоритмы с которыми настольный компьютер справляется легко благодаря куче инструкций на все случаи жизни и SIMD-расширениями могут работать на ARM-процессоре куда медленнее

Что там внутриbull Какая-то батарейка

Alexey Chubar
Причина различий в производительности с настольными системами конечно понятна - это необходимость компактого размера и скромного энергопотребления Однако высокая нагрузка на процессор и интенсивный обмен данными по сети всё равно быстро посадят любой аккумулятор Если ваша игра будет разряжать телефон за час никто вас любить не будет Включая Google и Apple которые всё жестче следят за энергопотреблением приложений Поэтому следует оптимизировать игру минимизируя нагрузку на ЦП и обмен данными

Что там внутриbull Какой-то графический ускоритель

ne

Alexey Chubar
Да в телефонах есть что-то вроде видеокарты Но опять же это не совсем 250-ваттный GeForce Графические ускорители в мобильных устройствах имееют ряд особенностей которые важно понимать для достижения высокой производительности О них я подробнее расскажу ниже

Что там внутриbull Какая-то оперативная памятьbull Её всегда мало

Alexey Chubar
Одна из таких особенностей - отсутствие собственной видеопамяти Для своих нужд графический процессор использует часть оперативной памяти устройства И это дополнительно осложняет жизнь разработчику потому что оперативной памяти вечно не хватает Не хватает её в частности из-за специфики мобильных ОС Даже если ты работаешь с флагманом у которого 3-4 гигабайта оперативки это не значит что твоё приложение может выжрать все эти 3 гига Мобильная ОС не церемонится с приложениями которые потребляют много памяти Она завершает их работу как только ей понадобится память для других задач Если приложение наглеет система может втихую прибить его даже если оно сейчас открыто и пользователь на него смотрит Однако ещё до этого с ростом потребления памяти производительность приложения будет падать так как ему будет всё сложнее найти свободный участок памяти для каких-либо сиюминутных вычислений и операций Поэтому нужно очень аккуратно работать с оперативной памятью

Зоопарк устройств

Alexey Chubar
Я не случайно говорил какой-токакая-то на предыдущих слайдах Аппаратных конфигураций в итоге получается очень много На рынке находится целый зоопарк устройств И чтобы завладеть максимальной аудиторией болшинство устрйоств нужно поддерживать Считалось что фрагментация - удел Android однако сейчас и у Apple накопилось значительное число устровйств на базе iOS При этом вопреки стереотипам далеко не все обладатели айфонов и айпадов каждый год меняют свой девайс на новый Многие играют на iPad 2 и iPad Mini 1st Gen где всего 512 МБ ОЗУ

Зоопарк устройств

240 MB ought to be enough for anyone ndash Gill Bates

Alexey Chubar
Эмпирически мы выявили лимит потребления памяти игрой позволяющий её работать на устройствах с 512 Мб ОЗУ - примерно 240 МБ памяти Сюда соответственно входит и динамическая память приложения и текстуры и звук и проч Это довольно жесткое ограничение которое легко нарушить

bull Падение FPSbull Чёрные квадраты вместо текстурbull laquoТихоеraquo завершение приложения без отчёта об ошибке

Зоопарк устройств

gt240 MB

Alexey Chubar
При привышении этого лимита на слабых девайсах наблюдаются неприятные эффекты

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Alexey Chubar
В таких суровых условиях на ум приходит одна общая рекомендация которая уже сформулирована в документации Unity

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Постоянно спрашивай себя ldquoА не ерунду ли я сейчас делаюrdquo- Примерный перевод

Alexey Chubar
В голове нужно постоянно держать возможные последствия своих действий для производительности игры на мобильном устройстве И разрабатывать игру сразу с учётом жестких требований Рассмотрим же какие конкретные аспекты игры влияют на производительность

Из-за чего всё тормозит

Alexey Chubar
Что же в нашей игре нагружает процессор жрёт память и мучает видеокарту Из-за чего приложение работает не так быстро как хотелось бы Причины вполне ожидаемые

Из-за чего всё тормозитbull Код

Alexey Chubar
Во-первых из-за того как написан вами программный код При этом здесь я не говорю о том что криво написанный код работает медленно Это и так понятно В случае с Unity порой прямо написанный код работает медленно И его приходится переписывать более криво

Из-за чего всё тормозитbull Код bull Ресурсы

Alexey Chubar
Во-вторых из-за неоптимального использования игровых ресурсов таких как 3D-модели текстуры анимации звуки и прочее

Импорт ресурсов

Alexey Chubar
Начнём с того что попроще - с игровых ресурсов Чтобы импортировать ресурс в проект Unity достаточно просто положить его в папку с проектом На слайде скриншот с их сайта И это действительно круто Однако настройки импорта по умолчанию зачастую не оптимальны особенно для мобильного приложения

Импорт ресурсов звук

Alexey Chubar
Это легко показать на примере звуков Вы кидаете MP3-мелодию в проект включаете её проигрывание на сцене всё работает Однако однажды мы вдруг обнаружили что звуки на уровне в игре занимают целых 30 МБ Притом что озвучка в принципе скромная звуки ударов и умений пара вскриков музыкальная тема и эмбиент

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 14: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

bull Какой-то странный процессорbull ARM x86 MIPShellip 32 и 64 bit

Что там внутри

ne

Alexey Chubar
Большинство устройств основаны на микроархитектуре ARMv7 которая значительно отличается от x86 Изначально это RISC-архитектура поэтому некоторые алгоритмы с которыми настольный компьютер справляется легко благодаря куче инструкций на все случаи жизни и SIMD-расширениями могут работать на ARM-процессоре куда медленнее

Что там внутриbull Какая-то батарейка

Alexey Chubar
Причина различий в производительности с настольными системами конечно понятна - это необходимость компактого размера и скромного энергопотребления Однако высокая нагрузка на процессор и интенсивный обмен данными по сети всё равно быстро посадят любой аккумулятор Если ваша игра будет разряжать телефон за час никто вас любить не будет Включая Google и Apple которые всё жестче следят за энергопотреблением приложений Поэтому следует оптимизировать игру минимизируя нагрузку на ЦП и обмен данными

Что там внутриbull Какой-то графический ускоритель

ne

Alexey Chubar
Да в телефонах есть что-то вроде видеокарты Но опять же это не совсем 250-ваттный GeForce Графические ускорители в мобильных устройствах имееют ряд особенностей которые важно понимать для достижения высокой производительности О них я подробнее расскажу ниже

Что там внутриbull Какая-то оперативная памятьbull Её всегда мало

Alexey Chubar
Одна из таких особенностей - отсутствие собственной видеопамяти Для своих нужд графический процессор использует часть оперативной памяти устройства И это дополнительно осложняет жизнь разработчику потому что оперативной памяти вечно не хватает Не хватает её в частности из-за специфики мобильных ОС Даже если ты работаешь с флагманом у которого 3-4 гигабайта оперативки это не значит что твоё приложение может выжрать все эти 3 гига Мобильная ОС не церемонится с приложениями которые потребляют много памяти Она завершает их работу как только ей понадобится память для других задач Если приложение наглеет система может втихую прибить его даже если оно сейчас открыто и пользователь на него смотрит Однако ещё до этого с ростом потребления памяти производительность приложения будет падать так как ему будет всё сложнее найти свободный участок памяти для каких-либо сиюминутных вычислений и операций Поэтому нужно очень аккуратно работать с оперативной памятью

Зоопарк устройств

Alexey Chubar
Я не случайно говорил какой-токакая-то на предыдущих слайдах Аппаратных конфигураций в итоге получается очень много На рынке находится целый зоопарк устройств И чтобы завладеть максимальной аудиторией болшинство устрйоств нужно поддерживать Считалось что фрагментация - удел Android однако сейчас и у Apple накопилось значительное число устровйств на базе iOS При этом вопреки стереотипам далеко не все обладатели айфонов и айпадов каждый год меняют свой девайс на новый Многие играют на iPad 2 и iPad Mini 1st Gen где всего 512 МБ ОЗУ

Зоопарк устройств

240 MB ought to be enough for anyone ndash Gill Bates

Alexey Chubar
Эмпирически мы выявили лимит потребления памяти игрой позволяющий её работать на устройствах с 512 Мб ОЗУ - примерно 240 МБ памяти Сюда соответственно входит и динамическая память приложения и текстуры и звук и проч Это довольно жесткое ограничение которое легко нарушить

bull Падение FPSbull Чёрные квадраты вместо текстурbull laquoТихоеraquo завершение приложения без отчёта об ошибке

Зоопарк устройств

gt240 MB

Alexey Chubar
При привышении этого лимита на слабых девайсах наблюдаются неприятные эффекты

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Alexey Chubar
В таких суровых условиях на ум приходит одна общая рекомендация которая уже сформулирована в документации Unity

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Постоянно спрашивай себя ldquoА не ерунду ли я сейчас делаюrdquo- Примерный перевод

Alexey Chubar
В голове нужно постоянно держать возможные последствия своих действий для производительности игры на мобильном устройстве И разрабатывать игру сразу с учётом жестких требований Рассмотрим же какие конкретные аспекты игры влияют на производительность

Из-за чего всё тормозит

Alexey Chubar
Что же в нашей игре нагружает процессор жрёт память и мучает видеокарту Из-за чего приложение работает не так быстро как хотелось бы Причины вполне ожидаемые

Из-за чего всё тормозитbull Код

Alexey Chubar
Во-первых из-за того как написан вами программный код При этом здесь я не говорю о том что криво написанный код работает медленно Это и так понятно В случае с Unity порой прямо написанный код работает медленно И его приходится переписывать более криво

Из-за чего всё тормозитbull Код bull Ресурсы

Alexey Chubar
Во-вторых из-за неоптимального использования игровых ресурсов таких как 3D-модели текстуры анимации звуки и прочее

Импорт ресурсов

Alexey Chubar
Начнём с того что попроще - с игровых ресурсов Чтобы импортировать ресурс в проект Unity достаточно просто положить его в папку с проектом На слайде скриншот с их сайта И это действительно круто Однако настройки импорта по умолчанию зачастую не оптимальны особенно для мобильного приложения

Импорт ресурсов звук

Alexey Chubar
Это легко показать на примере звуков Вы кидаете MP3-мелодию в проект включаете её проигрывание на сцене всё работает Однако однажды мы вдруг обнаружили что звуки на уровне в игре занимают целых 30 МБ Притом что озвучка в принципе скромная звуки ударов и умений пара вскриков музыкальная тема и эмбиент

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 15: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Что там внутриbull Какая-то батарейка

Alexey Chubar
Причина различий в производительности с настольными системами конечно понятна - это необходимость компактого размера и скромного энергопотребления Однако высокая нагрузка на процессор и интенсивный обмен данными по сети всё равно быстро посадят любой аккумулятор Если ваша игра будет разряжать телефон за час никто вас любить не будет Включая Google и Apple которые всё жестче следят за энергопотреблением приложений Поэтому следует оптимизировать игру минимизируя нагрузку на ЦП и обмен данными

Что там внутриbull Какой-то графический ускоритель

ne

Alexey Chubar
Да в телефонах есть что-то вроде видеокарты Но опять же это не совсем 250-ваттный GeForce Графические ускорители в мобильных устройствах имееют ряд особенностей которые важно понимать для достижения высокой производительности О них я подробнее расскажу ниже

Что там внутриbull Какая-то оперативная памятьbull Её всегда мало

Alexey Chubar
Одна из таких особенностей - отсутствие собственной видеопамяти Для своих нужд графический процессор использует часть оперативной памяти устройства И это дополнительно осложняет жизнь разработчику потому что оперативной памяти вечно не хватает Не хватает её в частности из-за специфики мобильных ОС Даже если ты работаешь с флагманом у которого 3-4 гигабайта оперативки это не значит что твоё приложение может выжрать все эти 3 гига Мобильная ОС не церемонится с приложениями которые потребляют много памяти Она завершает их работу как только ей понадобится память для других задач Если приложение наглеет система может втихую прибить его даже если оно сейчас открыто и пользователь на него смотрит Однако ещё до этого с ростом потребления памяти производительность приложения будет падать так как ему будет всё сложнее найти свободный участок памяти для каких-либо сиюминутных вычислений и операций Поэтому нужно очень аккуратно работать с оперативной памятью

Зоопарк устройств

Alexey Chubar
Я не случайно говорил какой-токакая-то на предыдущих слайдах Аппаратных конфигураций в итоге получается очень много На рынке находится целый зоопарк устройств И чтобы завладеть максимальной аудиторией болшинство устрйоств нужно поддерживать Считалось что фрагментация - удел Android однако сейчас и у Apple накопилось значительное число устровйств на базе iOS При этом вопреки стереотипам далеко не все обладатели айфонов и айпадов каждый год меняют свой девайс на новый Многие играют на iPad 2 и iPad Mini 1st Gen где всего 512 МБ ОЗУ

Зоопарк устройств

240 MB ought to be enough for anyone ndash Gill Bates

Alexey Chubar
Эмпирически мы выявили лимит потребления памяти игрой позволяющий её работать на устройствах с 512 Мб ОЗУ - примерно 240 МБ памяти Сюда соответственно входит и динамическая память приложения и текстуры и звук и проч Это довольно жесткое ограничение которое легко нарушить

bull Падение FPSbull Чёрные квадраты вместо текстурbull laquoТихоеraquo завершение приложения без отчёта об ошибке

Зоопарк устройств

gt240 MB

Alexey Chubar
При привышении этого лимита на слабых девайсах наблюдаются неприятные эффекты

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Alexey Chubar
В таких суровых условиях на ум приходит одна общая рекомендация которая уже сформулирована в документации Unity

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Постоянно спрашивай себя ldquoА не ерунду ли я сейчас делаюrdquo- Примерный перевод

Alexey Chubar
В голове нужно постоянно держать возможные последствия своих действий для производительности игры на мобильном устройстве И разрабатывать игру сразу с учётом жестких требований Рассмотрим же какие конкретные аспекты игры влияют на производительность

Из-за чего всё тормозит

Alexey Chubar
Что же в нашей игре нагружает процессор жрёт память и мучает видеокарту Из-за чего приложение работает не так быстро как хотелось бы Причины вполне ожидаемые

Из-за чего всё тормозитbull Код

Alexey Chubar
Во-первых из-за того как написан вами программный код При этом здесь я не говорю о том что криво написанный код работает медленно Это и так понятно В случае с Unity порой прямо написанный код работает медленно И его приходится переписывать более криво

Из-за чего всё тормозитbull Код bull Ресурсы

Alexey Chubar
Во-вторых из-за неоптимального использования игровых ресурсов таких как 3D-модели текстуры анимации звуки и прочее

Импорт ресурсов

Alexey Chubar
Начнём с того что попроще - с игровых ресурсов Чтобы импортировать ресурс в проект Unity достаточно просто положить его в папку с проектом На слайде скриншот с их сайта И это действительно круто Однако настройки импорта по умолчанию зачастую не оптимальны особенно для мобильного приложения

Импорт ресурсов звук

Alexey Chubar
Это легко показать на примере звуков Вы кидаете MP3-мелодию в проект включаете её проигрывание на сцене всё работает Однако однажды мы вдруг обнаружили что звуки на уровне в игре занимают целых 30 МБ Притом что озвучка в принципе скромная звуки ударов и умений пара вскриков музыкальная тема и эмбиент

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 16: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Что там внутриbull Какой-то графический ускоритель

ne

Alexey Chubar
Да в телефонах есть что-то вроде видеокарты Но опять же это не совсем 250-ваттный GeForce Графические ускорители в мобильных устройствах имееют ряд особенностей которые важно понимать для достижения высокой производительности О них я подробнее расскажу ниже

Что там внутриbull Какая-то оперативная памятьbull Её всегда мало

Alexey Chubar
Одна из таких особенностей - отсутствие собственной видеопамяти Для своих нужд графический процессор использует часть оперативной памяти устройства И это дополнительно осложняет жизнь разработчику потому что оперативной памяти вечно не хватает Не хватает её в частности из-за специфики мобильных ОС Даже если ты работаешь с флагманом у которого 3-4 гигабайта оперативки это не значит что твоё приложение может выжрать все эти 3 гига Мобильная ОС не церемонится с приложениями которые потребляют много памяти Она завершает их работу как только ей понадобится память для других задач Если приложение наглеет система может втихую прибить его даже если оно сейчас открыто и пользователь на него смотрит Однако ещё до этого с ростом потребления памяти производительность приложения будет падать так как ему будет всё сложнее найти свободный участок памяти для каких-либо сиюминутных вычислений и операций Поэтому нужно очень аккуратно работать с оперативной памятью

Зоопарк устройств

Alexey Chubar
Я не случайно говорил какой-токакая-то на предыдущих слайдах Аппаратных конфигураций в итоге получается очень много На рынке находится целый зоопарк устройств И чтобы завладеть максимальной аудиторией болшинство устрйоств нужно поддерживать Считалось что фрагментация - удел Android однако сейчас и у Apple накопилось значительное число устровйств на базе iOS При этом вопреки стереотипам далеко не все обладатели айфонов и айпадов каждый год меняют свой девайс на новый Многие играют на iPad 2 и iPad Mini 1st Gen где всего 512 МБ ОЗУ

Зоопарк устройств

240 MB ought to be enough for anyone ndash Gill Bates

Alexey Chubar
Эмпирически мы выявили лимит потребления памяти игрой позволяющий её работать на устройствах с 512 Мб ОЗУ - примерно 240 МБ памяти Сюда соответственно входит и динамическая память приложения и текстуры и звук и проч Это довольно жесткое ограничение которое легко нарушить

bull Падение FPSbull Чёрные квадраты вместо текстурbull laquoТихоеraquo завершение приложения без отчёта об ошибке

Зоопарк устройств

gt240 MB

Alexey Chubar
При привышении этого лимита на слабых девайсах наблюдаются неприятные эффекты

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Alexey Chubar
В таких суровых условиях на ум приходит одна общая рекомендация которая уже сформулирована в документации Unity

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Постоянно спрашивай себя ldquoА не ерунду ли я сейчас делаюrdquo- Примерный перевод

Alexey Chubar
В голове нужно постоянно держать возможные последствия своих действий для производительности игры на мобильном устройстве И разрабатывать игру сразу с учётом жестких требований Рассмотрим же какие конкретные аспекты игры влияют на производительность

Из-за чего всё тормозит

Alexey Chubar
Что же в нашей игре нагружает процессор жрёт память и мучает видеокарту Из-за чего приложение работает не так быстро как хотелось бы Причины вполне ожидаемые

Из-за чего всё тормозитbull Код

Alexey Chubar
Во-первых из-за того как написан вами программный код При этом здесь я не говорю о том что криво написанный код работает медленно Это и так понятно В случае с Unity порой прямо написанный код работает медленно И его приходится переписывать более криво

Из-за чего всё тормозитbull Код bull Ресурсы

Alexey Chubar
Во-вторых из-за неоптимального использования игровых ресурсов таких как 3D-модели текстуры анимации звуки и прочее

Импорт ресурсов

Alexey Chubar
Начнём с того что попроще - с игровых ресурсов Чтобы импортировать ресурс в проект Unity достаточно просто положить его в папку с проектом На слайде скриншот с их сайта И это действительно круто Однако настройки импорта по умолчанию зачастую не оптимальны особенно для мобильного приложения

Импорт ресурсов звук

Alexey Chubar
Это легко показать на примере звуков Вы кидаете MP3-мелодию в проект включаете её проигрывание на сцене всё работает Однако однажды мы вдруг обнаружили что звуки на уровне в игре занимают целых 30 МБ Притом что озвучка в принципе скромная звуки ударов и умений пара вскриков музыкальная тема и эмбиент

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 17: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Что там внутриbull Какая-то оперативная памятьbull Её всегда мало

Alexey Chubar
Одна из таких особенностей - отсутствие собственной видеопамяти Для своих нужд графический процессор использует часть оперативной памяти устройства И это дополнительно осложняет жизнь разработчику потому что оперативной памяти вечно не хватает Не хватает её в частности из-за специфики мобильных ОС Даже если ты работаешь с флагманом у которого 3-4 гигабайта оперативки это не значит что твоё приложение может выжрать все эти 3 гига Мобильная ОС не церемонится с приложениями которые потребляют много памяти Она завершает их работу как только ей понадобится память для других задач Если приложение наглеет система может втихую прибить его даже если оно сейчас открыто и пользователь на него смотрит Однако ещё до этого с ростом потребления памяти производительность приложения будет падать так как ему будет всё сложнее найти свободный участок памяти для каких-либо сиюминутных вычислений и операций Поэтому нужно очень аккуратно работать с оперативной памятью

Зоопарк устройств

Alexey Chubar
Я не случайно говорил какой-токакая-то на предыдущих слайдах Аппаратных конфигураций в итоге получается очень много На рынке находится целый зоопарк устройств И чтобы завладеть максимальной аудиторией болшинство устрйоств нужно поддерживать Считалось что фрагментация - удел Android однако сейчас и у Apple накопилось значительное число устровйств на базе iOS При этом вопреки стереотипам далеко не все обладатели айфонов и айпадов каждый год меняют свой девайс на новый Многие играют на iPad 2 и iPad Mini 1st Gen где всего 512 МБ ОЗУ

Зоопарк устройств

240 MB ought to be enough for anyone ndash Gill Bates

Alexey Chubar
Эмпирически мы выявили лимит потребления памяти игрой позволяющий её работать на устройствах с 512 Мб ОЗУ - примерно 240 МБ памяти Сюда соответственно входит и динамическая память приложения и текстуры и звук и проч Это довольно жесткое ограничение которое легко нарушить

bull Падение FPSbull Чёрные квадраты вместо текстурbull laquoТихоеraquo завершение приложения без отчёта об ошибке

Зоопарк устройств

gt240 MB

Alexey Chubar
При привышении этого лимита на слабых девайсах наблюдаются неприятные эффекты

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Alexey Chubar
В таких суровых условиях на ум приходит одна общая рекомендация которая уже сформулирована в документации Unity

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Постоянно спрашивай себя ldquoА не ерунду ли я сейчас делаюrdquo- Примерный перевод

Alexey Chubar
В голове нужно постоянно держать возможные последствия своих действий для производительности игры на мобильном устройстве И разрабатывать игру сразу с учётом жестких требований Рассмотрим же какие конкретные аспекты игры влияют на производительность

Из-за чего всё тормозит

Alexey Chubar
Что же в нашей игре нагружает процессор жрёт память и мучает видеокарту Из-за чего приложение работает не так быстро как хотелось бы Причины вполне ожидаемые

Из-за чего всё тормозитbull Код

Alexey Chubar
Во-первых из-за того как написан вами программный код При этом здесь я не говорю о том что криво написанный код работает медленно Это и так понятно В случае с Unity порой прямо написанный код работает медленно И его приходится переписывать более криво

Из-за чего всё тормозитbull Код bull Ресурсы

Alexey Chubar
Во-вторых из-за неоптимального использования игровых ресурсов таких как 3D-модели текстуры анимации звуки и прочее

Импорт ресурсов

Alexey Chubar
Начнём с того что попроще - с игровых ресурсов Чтобы импортировать ресурс в проект Unity достаточно просто положить его в папку с проектом На слайде скриншот с их сайта И это действительно круто Однако настройки импорта по умолчанию зачастую не оптимальны особенно для мобильного приложения

Импорт ресурсов звук

Alexey Chubar
Это легко показать на примере звуков Вы кидаете MP3-мелодию в проект включаете её проигрывание на сцене всё работает Однако однажды мы вдруг обнаружили что звуки на уровне в игре занимают целых 30 МБ Притом что озвучка в принципе скромная звуки ударов и умений пара вскриков музыкальная тема и эмбиент

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 18: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Зоопарк устройств

Alexey Chubar
Я не случайно говорил какой-токакая-то на предыдущих слайдах Аппаратных конфигураций в итоге получается очень много На рынке находится целый зоопарк устройств И чтобы завладеть максимальной аудиторией болшинство устрйоств нужно поддерживать Считалось что фрагментация - удел Android однако сейчас и у Apple накопилось значительное число устровйств на базе iOS При этом вопреки стереотипам далеко не все обладатели айфонов и айпадов каждый год меняют свой девайс на новый Многие играют на iPad 2 и iPad Mini 1st Gen где всего 512 МБ ОЗУ

Зоопарк устройств

240 MB ought to be enough for anyone ndash Gill Bates

Alexey Chubar
Эмпирически мы выявили лимит потребления памяти игрой позволяющий её работать на устройствах с 512 Мб ОЗУ - примерно 240 МБ памяти Сюда соответственно входит и динамическая память приложения и текстуры и звук и проч Это довольно жесткое ограничение которое легко нарушить

bull Падение FPSbull Чёрные квадраты вместо текстурbull laquoТихоеraquo завершение приложения без отчёта об ошибке

Зоопарк устройств

gt240 MB

Alexey Chubar
При привышении этого лимита на слабых девайсах наблюдаются неприятные эффекты

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Alexey Chubar
В таких суровых условиях на ум приходит одна общая рекомендация которая уже сформулирована в документации Unity

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Постоянно спрашивай себя ldquoА не ерунду ли я сейчас делаюrdquo- Примерный перевод

Alexey Chubar
В голове нужно постоянно держать возможные последствия своих действий для производительности игры на мобильном устройстве И разрабатывать игру сразу с учётом жестких требований Рассмотрим же какие конкретные аспекты игры влияют на производительность

Из-за чего всё тормозит

Alexey Chubar
Что же в нашей игре нагружает процессор жрёт память и мучает видеокарту Из-за чего приложение работает не так быстро как хотелось бы Причины вполне ожидаемые

Из-за чего всё тормозитbull Код

Alexey Chubar
Во-первых из-за того как написан вами программный код При этом здесь я не говорю о том что криво написанный код работает медленно Это и так понятно В случае с Unity порой прямо написанный код работает медленно И его приходится переписывать более криво

Из-за чего всё тормозитbull Код bull Ресурсы

Alexey Chubar
Во-вторых из-за неоптимального использования игровых ресурсов таких как 3D-модели текстуры анимации звуки и прочее

Импорт ресурсов

Alexey Chubar
Начнём с того что попроще - с игровых ресурсов Чтобы импортировать ресурс в проект Unity достаточно просто положить его в папку с проектом На слайде скриншот с их сайта И это действительно круто Однако настройки импорта по умолчанию зачастую не оптимальны особенно для мобильного приложения

Импорт ресурсов звук

Alexey Chubar
Это легко показать на примере звуков Вы кидаете MP3-мелодию в проект включаете её проигрывание на сцене всё работает Однако однажды мы вдруг обнаружили что звуки на уровне в игре занимают целых 30 МБ Притом что озвучка в принципе скромная звуки ударов и умений пара вскриков музыкальная тема и эмбиент

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 19: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Зоопарк устройств

240 MB ought to be enough for anyone ndash Gill Bates

Alexey Chubar
Эмпирически мы выявили лимит потребления памяти игрой позволяющий её работать на устройствах с 512 Мб ОЗУ - примерно 240 МБ памяти Сюда соответственно входит и динамическая память приложения и текстуры и звук и проч Это довольно жесткое ограничение которое легко нарушить

bull Падение FPSbull Чёрные квадраты вместо текстурbull laquoТихоеraquo завершение приложения без отчёта об ошибке

Зоопарк устройств

gt240 MB

Alexey Chubar
При привышении этого лимита на слабых девайсах наблюдаются неприятные эффекты

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Alexey Chubar
В таких суровых условиях на ум приходит одна общая рекомендация которая уже сформулирована в документации Unity

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Постоянно спрашивай себя ldquoА не ерунду ли я сейчас делаюrdquo- Примерный перевод

Alexey Chubar
В голове нужно постоянно держать возможные последствия своих действий для производительности игры на мобильном устройстве И разрабатывать игру сразу с учётом жестких требований Рассмотрим же какие конкретные аспекты игры влияют на производительность

Из-за чего всё тормозит

Alexey Chubar
Что же в нашей игре нагружает процессор жрёт память и мучает видеокарту Из-за чего приложение работает не так быстро как хотелось бы Причины вполне ожидаемые

Из-за чего всё тормозитbull Код

Alexey Chubar
Во-первых из-за того как написан вами программный код При этом здесь я не говорю о том что криво написанный код работает медленно Это и так понятно В случае с Unity порой прямо написанный код работает медленно И его приходится переписывать более криво

Из-за чего всё тормозитbull Код bull Ресурсы

Alexey Chubar
Во-вторых из-за неоптимального использования игровых ресурсов таких как 3D-модели текстуры анимации звуки и прочее

Импорт ресурсов

Alexey Chubar
Начнём с того что попроще - с игровых ресурсов Чтобы импортировать ресурс в проект Unity достаточно просто положить его в папку с проектом На слайде скриншот с их сайта И это действительно круто Однако настройки импорта по умолчанию зачастую не оптимальны особенно для мобильного приложения

Импорт ресурсов звук

Alexey Chubar
Это легко показать на примере звуков Вы кидаете MP3-мелодию в проект включаете её проигрывание на сцене всё работает Однако однажды мы вдруг обнаружили что звуки на уровне в игре занимают целых 30 МБ Притом что озвучка в принципе скромная звуки ударов и умений пара вскриков музыкальная тема и эмбиент

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 20: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

bull Падение FPSbull Чёрные квадраты вместо текстурbull laquoТихоеraquo завершение приложения без отчёта об ошибке

Зоопарк устройств

gt240 MB

Alexey Chubar
При привышении этого лимита на слабых девайсах наблюдаются неприятные эффекты

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Alexey Chubar
В таких суровых условиях на ум приходит одна общая рекомендация которая уже сформулирована в документации Unity

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Постоянно спрашивай себя ldquoА не ерунду ли я сейчас делаюrdquo- Примерный перевод

Alexey Chubar
В голове нужно постоянно держать возможные последствия своих действий для производительности игры на мобильном устройстве И разрабатывать игру сразу с учётом жестких требований Рассмотрим же какие конкретные аспекты игры влияют на производительность

Из-за чего всё тормозит

Alexey Chubar
Что же в нашей игре нагружает процессор жрёт память и мучает видеокарту Из-за чего приложение работает не так быстро как хотелось бы Причины вполне ожидаемые

Из-за чего всё тормозитbull Код

Alexey Chubar
Во-первых из-за того как написан вами программный код При этом здесь я не говорю о том что криво написанный код работает медленно Это и так понятно В случае с Unity порой прямо написанный код работает медленно И его приходится переписывать более криво

Из-за чего всё тормозитbull Код bull Ресурсы

Alexey Chubar
Во-вторых из-за неоптимального использования игровых ресурсов таких как 3D-модели текстуры анимации звуки и прочее

Импорт ресурсов

Alexey Chubar
Начнём с того что попроще - с игровых ресурсов Чтобы импортировать ресурс в проект Unity достаточно просто положить его в папку с проектом На слайде скриншот с их сайта И это действительно круто Однако настройки импорта по умолчанию зачастую не оптимальны особенно для мобильного приложения

Импорт ресурсов звук

Alexey Chubar
Это легко показать на примере звуков Вы кидаете MP3-мелодию в проект включаете её проигрывание на сцене всё работает Однако однажды мы вдруг обнаружили что звуки на уровне в игре занимают целых 30 МБ Притом что озвучка в принципе скромная звуки ударов и умений пара вскриков музыкальная тема и эмбиент

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 21: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Alexey Chubar
В таких суровых условиях на ум приходит одна общая рекомендация которая уже сформулирована в документации Unity

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Постоянно спрашивай себя ldquoА не ерунду ли я сейчас делаюrdquo- Примерный перевод

Alexey Chubar
В голове нужно постоянно держать возможные последствия своих действий для производительности игры на мобильном устройстве И разрабатывать игру сразу с учётом жестких требований Рассмотрим же какие конкретные аспекты игры влияют на производительность

Из-за чего всё тормозит

Alexey Chubar
Что же в нашей игре нагружает процессор жрёт память и мучает видеокарту Из-за чего приложение работает не так быстро как хотелось бы Причины вполне ожидаемые

Из-за чего всё тормозитbull Код

Alexey Chubar
Во-первых из-за того как написан вами программный код При этом здесь я не говорю о том что криво написанный код работает медленно Это и так понятно В случае с Unity порой прямо написанный код работает медленно И его приходится переписывать более криво

Из-за чего всё тормозитbull Код bull Ресурсы

Alexey Chubar
Во-вторых из-за неоптимального использования игровых ресурсов таких как 3D-модели текстуры анимации звуки и прочее

Импорт ресурсов

Alexey Chubar
Начнём с того что попроще - с игровых ресурсов Чтобы импортировать ресурс в проект Unity достаточно просто положить его в папку с проектом На слайде скриншот с их сайта И это действительно круто Однако настройки импорта по умолчанию зачастую не оптимальны особенно для мобильного приложения

Импорт ресурсов звук

Alexey Chubar
Это легко показать на примере звуков Вы кидаете MP3-мелодию в проект включаете её проигрывание на сцене всё работает Однако однажды мы вдруг обнаружили что звуки на уровне в игре занимают целых 30 МБ Притом что озвучка в принципе скромная звуки ударов и умений пара вскриков музыкальная тема и эмбиент

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 22: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Главный советldquoMake optimization a design consideration not a final steprdquo

- Unity Docs

Постоянно спрашивай себя ldquoА не ерунду ли я сейчас делаюrdquo- Примерный перевод

Alexey Chubar
В голове нужно постоянно держать возможные последствия своих действий для производительности игры на мобильном устройстве И разрабатывать игру сразу с учётом жестких требований Рассмотрим же какие конкретные аспекты игры влияют на производительность

Из-за чего всё тормозит

Alexey Chubar
Что же в нашей игре нагружает процессор жрёт память и мучает видеокарту Из-за чего приложение работает не так быстро как хотелось бы Причины вполне ожидаемые

Из-за чего всё тормозитbull Код

Alexey Chubar
Во-первых из-за того как написан вами программный код При этом здесь я не говорю о том что криво написанный код работает медленно Это и так понятно В случае с Unity порой прямо написанный код работает медленно И его приходится переписывать более криво

Из-за чего всё тормозитbull Код bull Ресурсы

Alexey Chubar
Во-вторых из-за неоптимального использования игровых ресурсов таких как 3D-модели текстуры анимации звуки и прочее

Импорт ресурсов

Alexey Chubar
Начнём с того что попроще - с игровых ресурсов Чтобы импортировать ресурс в проект Unity достаточно просто положить его в папку с проектом На слайде скриншот с их сайта И это действительно круто Однако настройки импорта по умолчанию зачастую не оптимальны особенно для мобильного приложения

Импорт ресурсов звук

Alexey Chubar
Это легко показать на примере звуков Вы кидаете MP3-мелодию в проект включаете её проигрывание на сцене всё работает Однако однажды мы вдруг обнаружили что звуки на уровне в игре занимают целых 30 МБ Притом что озвучка в принципе скромная звуки ударов и умений пара вскриков музыкальная тема и эмбиент

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 23: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Из-за чего всё тормозит

Alexey Chubar
Что же в нашей игре нагружает процессор жрёт память и мучает видеокарту Из-за чего приложение работает не так быстро как хотелось бы Причины вполне ожидаемые

Из-за чего всё тормозитbull Код

Alexey Chubar
Во-первых из-за того как написан вами программный код При этом здесь я не говорю о том что криво написанный код работает медленно Это и так понятно В случае с Unity порой прямо написанный код работает медленно И его приходится переписывать более криво

Из-за чего всё тормозитbull Код bull Ресурсы

Alexey Chubar
Во-вторых из-за неоптимального использования игровых ресурсов таких как 3D-модели текстуры анимации звуки и прочее

Импорт ресурсов

Alexey Chubar
Начнём с того что попроще - с игровых ресурсов Чтобы импортировать ресурс в проект Unity достаточно просто положить его в папку с проектом На слайде скриншот с их сайта И это действительно круто Однако настройки импорта по умолчанию зачастую не оптимальны особенно для мобильного приложения

Импорт ресурсов звук

Alexey Chubar
Это легко показать на примере звуков Вы кидаете MP3-мелодию в проект включаете её проигрывание на сцене всё работает Однако однажды мы вдруг обнаружили что звуки на уровне в игре занимают целых 30 МБ Притом что озвучка в принципе скромная звуки ударов и умений пара вскриков музыкальная тема и эмбиент

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 24: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Из-за чего всё тормозитbull Код

Alexey Chubar
Во-первых из-за того как написан вами программный код При этом здесь я не говорю о том что криво написанный код работает медленно Это и так понятно В случае с Unity порой прямо написанный код работает медленно И его приходится переписывать более криво

Из-за чего всё тормозитbull Код bull Ресурсы

Alexey Chubar
Во-вторых из-за неоптимального использования игровых ресурсов таких как 3D-модели текстуры анимации звуки и прочее

Импорт ресурсов

Alexey Chubar
Начнём с того что попроще - с игровых ресурсов Чтобы импортировать ресурс в проект Unity достаточно просто положить его в папку с проектом На слайде скриншот с их сайта И это действительно круто Однако настройки импорта по умолчанию зачастую не оптимальны особенно для мобильного приложения

Импорт ресурсов звук

Alexey Chubar
Это легко показать на примере звуков Вы кидаете MP3-мелодию в проект включаете её проигрывание на сцене всё работает Однако однажды мы вдруг обнаружили что звуки на уровне в игре занимают целых 30 МБ Притом что озвучка в принципе скромная звуки ударов и умений пара вскриков музыкальная тема и эмбиент

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 25: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Из-за чего всё тормозитbull Код bull Ресурсы

Alexey Chubar
Во-вторых из-за неоптимального использования игровых ресурсов таких как 3D-модели текстуры анимации звуки и прочее

Импорт ресурсов

Alexey Chubar
Начнём с того что попроще - с игровых ресурсов Чтобы импортировать ресурс в проект Unity достаточно просто положить его в папку с проектом На слайде скриншот с их сайта И это действительно круто Однако настройки импорта по умолчанию зачастую не оптимальны особенно для мобильного приложения

Импорт ресурсов звук

Alexey Chubar
Это легко показать на примере звуков Вы кидаете MP3-мелодию в проект включаете её проигрывание на сцене всё работает Однако однажды мы вдруг обнаружили что звуки на уровне в игре занимают целых 30 МБ Притом что озвучка в принципе скромная звуки ударов и умений пара вскриков музыкальная тема и эмбиент

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 26: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Импорт ресурсов

Alexey Chubar
Начнём с того что попроще - с игровых ресурсов Чтобы импортировать ресурс в проект Unity достаточно просто положить его в папку с проектом На слайде скриншот с их сайта И это действительно круто Однако настройки импорта по умолчанию зачастую не оптимальны особенно для мобильного приложения

Импорт ресурсов звук

Alexey Chubar
Это легко показать на примере звуков Вы кидаете MP3-мелодию в проект включаете её проигрывание на сцене всё работает Однако однажды мы вдруг обнаружили что звуки на уровне в игре занимают целых 30 МБ Притом что озвучка в принципе скромная звуки ударов и умений пара вскриков музыкальная тема и эмбиент

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 27: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Импорт ресурсов звук

Alexey Chubar
Это легко показать на примере звуков Вы кидаете MP3-мелодию в проект включаете её проигрывание на сцене всё работает Однако однажды мы вдруг обнаружили что звуки на уровне в игре занимают целых 30 МБ Притом что озвучка в принципе скромная звуки ударов и умений пара вскриков музыкальная тема и эмбиент

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 28: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Оказалось что умолчанию все звуки добавляются в проект с опцией Decompress On Load - то есть при загрузке уровня они целиком раскодируются в WAV и размещаются в памяти Естественно это очень расточительно Несжатые звуки весят много

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 29: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Импорт ресурсов звук

16 bit 44100 Hz 2 channels = 1764 KBs

Alexey Chubar
Такой формат годится только для коротких звуков которые проигрываются очень часто Пусть они всегда лежат в памяти наготове Для более длинных и часто используемых звуков подойдёт Compressed In Memory - звук лежит в памяти в сжатом формате и раскодируется при проигрывании Для длинных звуков в особенности музыкальных тем подходит Streaming - чтение и декодирование с носителя устройства по кусочкам в процессе воспроизведения Последние 2 варианта нагружают процессор больше (Streaming имеет также оверхед на чтение с диска) но процессоры устрйоств оптимизированы для декодирования мультимедиа и негативный эффект от чуть увеличившейся нагрузки на CPU куда меньше чем от нехватки оперативной памяти
Alexey Chubar
Стоит также рассмотреть принудительное преобразование звуков в Mono это значительно уменьшит их вес в памяти и накладные расходы на декодирование

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 30: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Импорт ресурсов звукbull Сжатие MP3 на iOSbull Сжатие Vorbis на Androidbull Force Monobull Низкий битрейт (насколько возможно)

ne

Alexey Chubar
Unity вообще официально рекомендуют экономить на звуке на мобильных платформах поскольку его всё равно частенько никто не слушает Очень распространённый use case - человек играет в игру слушая фоном музыку в плеере Вот их официальные советы с Unite 2016

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 31: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Импорт ресурсов анимации

Alexey Chubar
Далее поговорим о 3D-анимациях С ними связаны похожие проблемы С точки зрения Unity анимация - это информация о том как со временем меняется в прострастве положение частей тела персонажа Соотвественно при проигрывании анимации эту информацию надо разместить в памяти и двигать объекты в соотвествии с ней Отсюда и берётся цена анимаций

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 32: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISS

Alexey Chubar
На этапе soft launch в нашей игре была пасхалка - игрок долгое время бездействуя в городе мог начать танцевать гангнам стайл Это была продолжительная и детализованная анимация В итоге выяснилось что она загружаясь вместе с персонажем игрока отжирает дополнительно 3 МБ памяти При очередной итерации оптимизации она пошла под нож (

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 33: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦП

Alexey Chubar
Вычисление положения анимируемых объектов может стать ресурсоёмкой задачей для ЦП если этих объектов много иили они имеют сложную иерархию костей Соответственно есть 2 пути снижения нагрузки

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 34: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектов

Alexey Chubar
Можно уменьшить количество объектов Компонент проигрывающий анимации можно настроить так чтобы он обсчитывал изменение положения только для видимых объектов Для этого нужно выбрать Cull Update Transforms или Cull Completely По умолчанию анимация обсчитывается всегда Стоит отметить однако что если какие-то внутриигровые события завязаны на анимацию а вы не анимируете невидимые объекты эти события не произойдут за кадром Это может стать источником багов Пример - не слышны звуки шагов человека у тебя за спиной

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 35: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Импорт ресурсов анимацииbull Сложные анимации занимают много памяти KISSbull Анимация большого числа объектов нагружает ЦПbull Можно уменьшить количество объектовbull Можно упростить объекты

Alexey Chubar
Также можно автоматически упростить струтктуру анимируемых объектов Их иерархия станет более плоской обсчёт анимации станет быстрее Разработчики игры War for the Overworld наблюдали снижение нагрузки на 50 Негативный эффект состоит в том что в результате оптимизации могут пропасть (стать частью более крупного объекта) участки персонажа нужные для геймплея Например точки крепления оружия и брони (кисть объединяется с предплечьем - куда вставлять меч) В таком случае их нужно будет явно указать в настройках импорта 3D-модели вручную или автоматизировать это при помощи скрипта
Alexey Chubar
httpwwwstrichnetcomhow-to-improve-the-performance-of-unity3d-animations

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 36: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Импорт ресурсов 3D-моделиbull Отключите ReadWritebull Много полигонов = много памятиbull Optimize Mesh Data

Alexey Chubar
Другой важнейший тип ассетов - это 3D модели На их счёт сложно дать общую рекомендацию тк влияние детализации моделей на производительность зависит от большого числа факторов - освещение тени используемые шейдеры способы обсчёта физики и прочее Однако очевидно что чем больше полигонов в модели тем больше места она займёт в памяти
Alexey Chubar
Можно оптимизировать отдельные составляющие моделей Например не трогать информацию о положении вершин но сжать информацию о нормалях
Alexey Chubar
При билде проекта под целевую платформу есть галочка Optimize mesh data Её настоятельно советуют оставлять включённой Она удалит из модели данные которые не нужны для используемых материалов Возможно стоит проверять не возникает ли в результате этой автоматической оптимизации визуальных артефактов (если вы программно заменяете материал)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 37: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Импорт ресурсов 3D-модели

Точно ли это всё понадобится

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

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 38: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Импорт ресурсов текстурыbull Сжатие обязательно

Android ETC iOS PVRTC

Alexey Chubar
Ну и конечно отдельно стоит сказать о текстурах Текстуры занимают зачастую самую большую долю памяти вашего приложения Поэтому нужно использовать сжатие текстур Притом как мы уже говорили выше отдельной памяти у видеоадаптера нет поэтому нельзя распаковать текстуру и закинуть её в видеопамять Даже в видеопамяти она должна храниться в сжатом формате Все графические ускорители устройств Apple поддерживают формат PVRTC все Андроиды несмотря на многообразие поддерживают ETC Формат сжатия можно (и нужно) настроить отдельно для каждой целевой платформы По умолчанию текстуры могут быть несжаты а это непозволительная роскошь (16 мегабайт будет весить картинка 2048х2048)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 39: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х1024 4MB

Alpha ETC 4 bit 512x512 128KB

-84

Alexey Chubar
Эти форматы сжатия обеспечивают существенное уменьшение размера но имеют ограничения Для ETC текстура должна быть квадратной и не иметь альфа-канала Альфа-канал как правило нужен в игре поэтому можно хранить его в отдельной текстуре Если запредельная чёткость контуров не нужна размер альфа-текстуры можно дополнительно уменьшить и получить солидный выигрыш в 84

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 40: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Импорт ресурсов текстуры

RGB ETC 4 bit 1024х1024 512KB

RGBA 32 bit 1024х512 2MB

Alpha ETC 4 bit 512x512 128KB

-69

Alexey Chubar
Выигрыш наблюдается даже по сравнению с не-квадратной текстурой так что это ограничение не слишком существенное
Alexey Chubar
Подход с разбиением текстуры на RGB и Alpha с последующим сжатием используется довольно широко однако долгое время не существовало официального решения для генерации альфа текстуры Мы использовали свою собственную утлилиту В недавнем обновлении похоже добавили-таки возможность делать это из коробки Сжимайте на здоровье

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 41: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

bull Не включайте ReadWritebull Отключите mipmaps если возможноbull Не используйте огромные текстурыbull 2048x2048 или 1024x1024 для UIbull 512x512 или меньше для текстур моделей

Импорт ресурсов текстуры

Допустимо если есть запас производительности GPU

-50

-33

Alexey Chubar
Советы с Unite 2016
Alexey Chubar
Даже сжатые тектуры должны иметь умеренный размер Первая причина - память опять же

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 42: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Fillrate amp overdraw

OK

Overdrawn

Alexey Chubar
Вторая - низкий fillrate мобильных устройств Им тяжело даётся отрисовка огромных полотнищ в высоком разрешении Ещё хуже когда эти полотнища рамещаются на экране перекрывая друг друга GPU приходится пыхтеть отрисовывая картинку несколько раз отбрасывая прошлые результаты Такая ситуация называется overdraw и с ней нужно бороться
Alexey Chubar
В Unity есть режим просмотра сцены для выявления Overdraw

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 43: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Alexey Chubar
Один из способов борьбы с Overdraw - запекать все элементы находящиеся на одном слое в одну текстуру Это можно делать даже на лету У нас все элементы заднего плана сначала отрисовываются в одну общую текстуру а потом эта текстура (уменьшенного разрешения) выводится на экран

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 44: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Борьба с overdrawHigh-res

background partsLower-res

RenderTextureHigh-DPI Device

Можно переиспользовать если камера не движется

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

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 45: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Борьба с overdraw

Нагрузка на GPU ниже когда камера статична

Alexey Chubar
Задники богатые поэтому выигыш от запекания существенный Видно как сильно падает нагрузка на ГП когда камера не двигается
>

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 46: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime

Alexey Chubar
Теперь самое весёлое Как работает в среде исполнения Unity ваш программный код Самое веселое потому что в случае с игровыми ресурсами всё более-менее понятно Ох я забыл включить сжатие текстура отожрала у меня всю память В случае с кодом связь действий и последствий может быть менее очевидной

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 47: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

Alexey Chubar

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 48: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime

C code

JS code

UnityScript code

CIL

CIL

CIL

Assemblydll

Sources Script compiler Mono runtime

JIT

AOT

OLD ampBAD

Alexey Chubar
Моно рантайм используется старый у него проблемы с аллокациями и освобождением памяти Этот рантайм - причина по которой память так сильно влияет на показатели игры

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 49: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtimebull Сборка мусора работает плохоbull Heap удваивается при достижении лимита И не уменьшается никогдаbull Производительность игры со временем снижается

Alexey Chubar
Garbage collector не отдаёт память системе Память течёт Со временем найти свободный блок памяти становится всё сложнее Каждая аллокация начинает занимать МНОГО времени Игра начинает тормозить (через N минут после начала игровой сессии)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 50: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime Garbage collectionReferenceType

class Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

ref1

Entryid 1337

phone 88005553535

name ref2

Stringvalue ldquoAyy Lmaordquo

ref3

Alexey Chubar
Heap never shrinks

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 51: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime Garbage collectionValueType

struct Entry uint id long phone string name

Thread stack (FAST)

var e1 = new Entry()

var e2 = e1

Managed heap (SLOW)

Entryid 1337

phone 88005553535

name ref1

Stringvalue ldquoAyy Lmaordquo

Entry (сopy)id 740

phone 88005553535

name ref2e2id = 740

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 52: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместно

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 53: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуй

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 54: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime аллокации

Refactor

public static class Modifiers public ListltModifiergt GetAll() var tmp = new ListltModifiergt()

FillStuff(tmp) return tmp

public static class Modifiers public void GetAll(ListltModifiergt to_fill) to_fillClear() FillStuff(to_fill)

public void Update() ListltModifiergt modifiers = ModifiersGetAll() DisplayModifiers(modifiers)

ListltModifiergt = new ListltModifiergt(CAPACITY)

public void Update() ModifiersGetAll(modifiers) DisplayModifiers(modifiers)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 55: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime аллокацииbull ValueType вместо ReferenceType где уместноbull Меньше временных объектов аллоцируй однажды и переиспользуйbull laquoГибридныеraquo контейнеры

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 56: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime аллокацииstruct HListltTgt IListltTgtгибридный контейнер

T val0

T val1

T val2

T val3

ListltTgt fallback T TT

myHListAdd(newVal)

Count gt Capacity

Truealloc fallback once

Falseno allocs

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 57: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime неявные аллокацииbull Regex

Alexey Chubar
Пример про мат-фильтр
Alexey Chubar
Многие привыкли к регулярным выражениям и используют их повсеместно в тч для простых операций вроде сравнения строк В юнити использование регулярок - очень дорогое удовольствие тк они создают много временных коллекций в памяти

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 58: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquo

Alexey Chubar
При каждой конкатенации создаётся новая строка

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 59: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methods

public void LoginWithID(int id) if(IsLoggedIn()) return

LoginWithDelegate( delegate() ProcessNewID(id) )

Вы ещё здесьhellip

hellip а эти объекты уже созданы в heap

ldquoidrdquo используется в closure копия создаётся в heap

Alexey Chubar
Новый объект создаётся при входе в scope

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 60: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

Alexey Chubar
LINQ тоже создаёт много тяжелых временных коллекций как и regexp

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 61: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreach

Alexey Chubar
Однако даже многие безобидные на первый взгляд вещи аллоцируют Например foreach (который ещё и тупо медленный в 4 раза медленнее for()) Им не рекомендует пользоваться Unity
Alexey Chubar
в не-юнити версии моно он не аллоцирует

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 62: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull using

Alexey Chubar
Оператор using для автоматического высвобождения ресурсов (RAII) IDisposable

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 63: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime неявные аллокацииbull Regexbull ldquoExcessiverdquo + ldquo strings ldquo + ldquoconcatrdquobull Closures amp anon methodsbull LINQ

bull foreachbull usingbull ArrayIndexOf и тпbull hellip

Alexey Chubar
Методы которые принимают object при передаче value-type параметров

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 64: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime boxingstruct Entry IPrintable

Thread stack

var e1 = new Entry()Entry

Managed heapvoid MyPrint(IPrintable p)

Object (boxed Entry)

IPrintable toPrint = e1MyPrint(toPrint) IPrintable ref1

Неявная аллокация

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 65: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 66: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime аллокации Unity APISkinnedMeshRenderer smr =

for(int i = 0 i lt smrbonesLength i++) Do stuff

SkinnedMeshRenderer smr = var bones = smrbones

for(int i = 0 i lt bonesLength i++) Do stuff

Аллоцирует массив ldquobonesrdquobonesLength раз

Аллоцирует массив ldquobonesrdquo1 раз

Alexey Chubar
Пример про дикие аллокации при переборе вершин в CharacterCombiner

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 67: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копия

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 68: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый раз

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 69: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилось

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 70: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getter

Alexey Chubar

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 71: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime аллокации Unity APIbull Если Unity API возвращает массив будет создана новая копияbull Каждый разbull Даже если значение не изменилосьbull Даже если это выглядит как безобидный getterbull laquoБезобидный getterraquo может скрывать внутри тяжёлые вычисления

public string name get return BadWordsFilterReplaceAll(datanameUnescape())

Alexey Chubar

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 72: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime прочееbull No inliningbull Вызов метода С = вызов в машинном кодеbull Property accessors = вызов метода

bull Это сказывается на скорости интенсивных вычисленийbull Do inlining yourself

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 73: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime прочееbull К свойствам некоторых компонентов можно обращаться по

имени (Animator Shader Material)bull Внутри имя каждый раз преобразовывается в хэшbull Вычисли хэш однажды и переиспользуй

materialSetColor(ldquo_Colorrdquo Colorwhite)animatorSetTrigger(ldquoattackrdquo)

static readonly int HASH_MAT_COLOR = ShaderPropertyToID(ldquo_Colorrdquo)static readonly int HASH_ANIM_ATTACK = AnimatorStringToHash(ldquoattackrdquo)

materialSetColor(HASH_MAT_COLOR Colorwhite)animatorSetTrigger(HASH_ANIM_ATTACK)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 74: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Код и runtime прочееbull Reflection is slowbull Text parsing is slow

bull Text parsers based on Reflection are super slow

Alexey Chubar
Пример про save-load DataItem

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 75: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Профайлинг

Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить
Alexey Chubar
Как же понять текущее положение дел с производительностью Узнать проседаете вы по памяти или по ЦП Есть ли запас производительности по ГП Можно ли кэшировать вещи или дешевле будет вычислять каждый раз Нужно профайлить

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 76: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Профайлингbull Встроенный профайлер Unity

Alexey Chubar
Юнити предоставляет возможность профилировать игру как в редакторе так и на устройстве

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 77: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Профайлингbull Встроенный профайлер Unitybull XCode Instruments

Alexey Chubar
Также для профайлинга игры на устройстве можно использовать сторонние средства для конкретной платформы

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 78: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

ПрофайлингСкорость итераций

Сложность интерпретации Точность Поддержка

ОС

Unity (редактор)

Очень высокая Низкая Низкая -

Unity(устройство) Низкая Низкая Средняя Любая

XCodeInstruments Низкая Средняя Очень

высокая Только iOS

Alexey Chubar
Профайлить на утсройстве неудобно тк билд длится долго Но надо Это как прививка Профайлить на устройстве нужно по ряду причин Первая - в редакторе для удобства разработки аллоцируются вещи которых не будет на устройстве Не стоит гоняться за призраками
Alexey Chubar
Во вторых в редакторе игра запущена на совсем другом железе
Alexey Chubar
Instruments общается с системой напрямую не оперируя понятиями юнити поэтому показывает наиболее точную картину потребления ресурсов Расплата за это - более высокая сложность интерпретации результатов Иногда сложно бывает соотнести результаты со своим кодом Но этот вариант всё равно предпочтительнее тк

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 79: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Профайлинг1401 MB

Unity

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 80: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Alexey Chubar
Пример про профайлинг недавнего обновления 200 vs 300 МБ
Alexey Chubar
XCode Instruments показывает реальную картину + аллокации с бектрейсом Ими стоит пользоваться хотя версия игры для iOS и собирается долго

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 81: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Профайлинг Unity врёт1401 MB

2620 MB

Unity

XCode

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 82: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработки

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 83: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPU

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 84: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатие

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 85: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdraw

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 86: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoа

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 87: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 88: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 89: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Summarybull Специфика мобильных платформ должна учитываться на всех этапах

разработкиbull Экономить RAM не менее важно чем ресурс CPU и GPUbull Разумный компромисс laquoКачество vs Памятьraquo для ассетов сжатиеbull Избегай overdrawbull Избегай аллокаций и boxingrsquoаbull Помни особенности Unity Mono Runtime (laquoheap never shrinksraquo)bull Помни особенности Unity API (laquono inliningraquo laquoarrays always allocatedraquo)bull Профайлить надо Часто Через Instruments

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание
Page 90: Производительность Unity3D: подводные камни / Алексей Чубарь (BIT.GAMES)

Спасибо за внимание

  • Производительность Unity3D подводные камни
  • Unity3D
  • Unity3D (2)
  • Unity3D (3)
  • Unity3D (4)
  • Unity3D (5)
  • Unity3D (6)
  • Unity3D (7)
  • Суровый мир мобильных игр
  • Суровый мир мобильных игр (2)
  • Суровый мир мобильных игр (3)
  • Суровый мир мобильных игр (4)
  • Что там внутри
  • Что там внутри (2)
  • Что там внутри (3)
  • Что там внутри (4)
  • Что там внутри (5)
  • Зоопарк устройств
  • Зоопарк устройств (2)
  • Зоопарк устройств (3)
  • Главный совет
  • Главный совет (2)
  • Из-за чего всё тормозит
  • Из-за чего всё тормозит (2)
  • Из-за чего всё тормозит (3)
  • Импорт ресурсов
  • Импорт ресурсов звук
  • Импорт ресурсов звук (2)
  • Импорт ресурсов звук (3)
  • Импорт ресурсов звук (4)
  • Импорт ресурсов анимации
  • Импорт ресурсов анимации (2)
  • Импорт ресурсов анимации (3)
  • Импорт ресурсов анимации (4)
  • Импорт ресурсов анимации (5)
  • Импорт ресурсов 3D-модели
  • Импорт ресурсов 3D-модели (2)
  • Импорт ресурсов текстуры
  • Импорт ресурсов текстуры (2)
  • Импорт ресурсов текстуры (3)
  • Импорт ресурсов текстуры (4)
  • Fillrate amp overdraw
  • Борьба с overdraw
  • Борьба с overdraw (2)
  • Борьба с overdraw (3)
  • Код и runtime
  • Код и runtime (2)
  • Код и runtime (3)
  • Код и runtime (4)
  • Код и runtime Garbage collection
  • Код и runtime Garbage collection (2)
  • Код и runtime аллокации
  • Код и runtime аллокации (2)
  • Код и runtime аллокации (3)
  • Код и runtime аллокации (4)
  • Код и runtime аллокации (5)
  • Код и runtime неявные аллокации
  • Код и runtime неявные аллокации (2)
  • Код и runtime неявные аллокации (3)
  • Код и runtime неявные аллокации (4)
  • Код и runtime неявные аллокации (5)
  • Код и runtime неявные аллокации (6)
  • Код и runtime неявные аллокации (7)
  • Код и runtime boxing
  • Код и runtime аллокации Unity API
  • Код и runtime аллокации Unity API (2)
  • Код и runtime аллокации Unity API (3)
  • Код и runtime аллокации Unity API (4)
  • Код и runtime аллокации Unity API (5)
  • Код и runtime аллокации Unity API (6)
  • Код и runtime аллокации Unity API (7)
  • Код и runtime прочее
  • Код и runtime прочее (2)
  • Код и runtime прочее (3)
  • Профайлинг
  • Профайлинг (2)
  • Профайлинг (3)
  • Профайлинг (4)
  • Профайлинг (5)
  • Профайлинг Unity врёт
  • Профайлинг Unity врёт (2)
  • Summary
  • Summary (2)
  • Summary (3)
  • Summary (4)
  • Summary (5)
  • Summary (6)
  • Summary (7)
  • Summary (8)
  • Спасибо за внимание