Представляем вам нашу новую электронную книгу: Стек технологий, ориентированных на данные (DOTS) Unity для продвинутых разработчиков

THOMAS KROGH-JACOBSEN / UNITY TECHNOLOGIESSenior Technical Content Marketing Manager
May 30, 2024|9 Мин
Представляем вам нашу новую электронную книгу: Стек технологий, ориентированных на данные (DOTS) Unity для продвинутых разработчиков
Эта веб-страница была переведена с помощью машинного перевода для вашего удобства. Мы не можем гарантировать точность или надежность переведенного контента. Если у вас есть вопросы о точности переведенного контента, обращайтесь к официальной английской версии веб-страницы.

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

Эта электронная книга объемом 50+ страниц, Введение в стек технологий, ориентированных на данные, для продвинутых разработчиков Unityтеперь можно скачать бесплатно. Используйте его в качестве учебника, чтобы лучше понять программирование, ориентированное на данные, и оценить, подходит ли DOTS для вашего следующего проекта. Если вы хотите начать новый проект на основе DOTS или внедрить DOTS для критически важных частей вашей игры, основанной на моноповедении, это руководство структурированно и понятно изложит все необходимые сведения.

Сейчас, когда Unity 6 находится в предварительной версии, а DOTS 1.0 уже готов к выпуску, самое время изучить возможности, которые открывает DOTS. Электронная книга, написанная Брайаном Уиллом, старшим инженером-программистом Unity, присоединяется к обновленным образцам Unity Learn, недавнему буткемпу DOTS и образцам GitHub в коллекции ресурсов, доступных разработчикам, которые хотят научиться работать с DOTS.

Руководство, которое поможет вам решить, является ли DOTS правильным выбором для вашей игры
В системе компонентов сущностей Unity все сущности с одинаковым набором типов компонентов хранятся вместе в одном "архетипе".

Наша цель в этой электронной книге - помочь вам принять обоснованное решение о том, является ли внедрение некоторых или всех пакетов и технологий DOTS правильным решением для вашего существующего или предстоящего проекта Unity. Каждая часть стека играет свою роль в повышении скорости и эффективности игры. Цель руководства - рассказать о каждой из этих частей, о том, как их можно использовать вместе, и об их общей основе - системе компонентов Unity Entity (ECS).

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

Давайте рассмотрим подробнее, что вы найдете в этой электронной книге.

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

Что входит в электронную книгу DOTS?
 Сцена из примера Firefighters, доступного на Github в EntityComponentSystemSamples

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

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

  • Система заданий на C#
  • Компилятор Burst
  • Коллекции
  • Математика
  • Организации
  • Энтитеты Графика
  • Физика единства
  • Неткод для сущностей

После описания каждой части стека вы познакомитесь с GitHub-репо EntityComponentSystemSamples, которое содержит множество примеров, знакомящих с базовыми и расширенными возможностями DOTS. Некоторые примеры из репозитория Github воспроизведены в новом курсе Unity Learn по DOTS " Знакомство с DOTS".

Другой ключевой раздел руководства DOTS - это приложение. Именно здесь Брайан Уилл дает подробные объяснения концепций, связанных с Unity ECS, включая распределение памяти и сборку мусора, кэш памяти и процессора, многопоточное программирование, ограничения объектно-ориентированного программирования и программирование, ориентированное на данные.

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

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

Что является виновником? Во многих проектах это рендеринг: Текстуры слишком большие, сетки слишком сложные, шейдеры слишком дорогие, или же неэффективно используются пакетная обработка, сортировка и LOD.

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

Так как же написать игровой код, который будет быстрым или, по крайней мере, не медленным?

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

Тогда стоит задать вопрос: "Почему мой процессорный код работает медленно?". Существует несколько распространенных подводных камней:

  • Сборка мусора приводит к заметным накладным расходам и паузам: Это происходит потому, что сборщик мусора служит автоматическим менеджером памяти, который управляет выделением и освобождением памяти для приложения. Сборка мусора не только требует затрат процессора и памяти, но и иногда приостанавливает выполнение всего кода на многие миллисекунды. Пользователи могут ощущать эти паузы как небольшие заминки или более навязчивые заикания.
  • Сгенерированный компилятором машинный код является неоптимальным: Некоторые компиляторы генерируют гораздо менее оптимизированный код, чем другие, причем результаты варьируются в зависимости от платформы.
  • Ядра процессора загружены недостаточно: Несмотря на то, что современные устройства низшего класса оснащены многоядерными процессорами, многие игры просто держат большую часть своей логики в главном потоке, потому что написание многопоточного кода часто затруднено и чревато ошибками.
  • Данные не дружественны к кэшу: Доступ к данным из кэша намного быстрее, чем получение их из основной памяти. Однако обращение к системной памяти может потребовать от процессора сотен циклов ожидания; вместо этого нужно, чтобы процессор как можно чаще считывал и записывал данные из своего кэша. Самый простой способ организовать это - читать и записывать память последовательно, поэтому наиболее удобным для кэша способом хранения данных являются плотно упакованные, смежные массивы. И наоборот, если ваши данные разбросаны по всей памяти несвязно, обращение к ним обычно вызывает множество дорогостоящих пропусков кэша; процессор запрашивает данные, которых нет в кэш-памяти, и вместо этого ему приходится извлекать их из более медленной основной памяти.
  • Код не дружественен к кэшу: Когда код выполняется, он должен быть загружен из системной памяти, если он еще не находится в кэше. Одна из стратегий заключается в том, чтобы вызывать функцию в как можно меньшем количестве мест, чтобы уменьшить частоту ее загрузки из системной памяти. Например, чем вызывать определенную функцию в разных местах кадра, лучше вызвать ее в одном цикле, чтобы код загружался не более одного раза за кадр.
  • Код чрезмерно абстрагирован: Помимо прочего, абстракция приводит к усложнению данных и кода, что усугубляет вышеупомянутые проблемы: управлять выделениями без сборки мусора становится сложнее; компилятор может не так эффективно оптимизировать; безопасная и эффективная многопоточность становится сложнее, а ваши данные и код становятся менее дружественными к кэшу. Вдобавок ко всему, абстракции имеют тенденцию распределять затраты на производительность, так что весь код становится медленнее, не оставляя вам явных узких мест для оптимизации.

Все вышеперечисленные недуги часто встречаются в проектах Unity. Давайте рассмотрим их подробнее:

  • Хотя C# позволяет создавать объекты с ручным распределением (то есть объекты, которые не собирают мусор), по умолчанию в C# и большинстве проектов Unity принято использовать экземпляры классов C#, которые собирают мусор. На практике пользователи Unity уже давно решают эту проблему с помощью техники, называемой пулингом (хотя пулинг, вероятно, противоречит цели использования языка, собирающего мусор, в первую очередь). Основное преимущество объединения объектов в пул заключается в эффективном повторном использовании объектов из заранее выделенного пула, что устраняет необходимость частого создания и удаления объектов.
  • В редакторе Unity код на C# обычно компилируется в машинный код с помощью компилятора Mono. Для автономных сборок можно добиться лучших результатов, используя IL2CPP (C# Intermediate Language, кросс-компилированный в C++), но это дает некоторые недостатки, например, увеличивает время сборки и усложняет поддержку модов.
  • Обычно проекты Unity выполняют весь свой код в главном потоке, отчасти потому, что это то, что Unity делает проще:
  • Функции событий Unity, такие как метод Update() в MonoBehaviours, выполняются в главном потоке.
  • Большинство API Unity можно безопасно вызывать только из главного потока.
  • Данные в типичном проекте Unity обычно структурированы как куча случайных объектов, разбросанных по всей памяти, что приводит к плохому использованию кэша. Опять же, отчасти это связано с тем, что Unity делает это легко:
  • GameObject и его компоненты выделяются отдельно, поэтому они часто оказываются в разных частях памяти.
  • Код в типичном проекте Unity, как правило, не дружелюбен к кэшу:
  • Обычный C# и API Unity поощряют объектно-ориентированный стиль кода, который склоняется к многочисленным маленьким методам и сложным цепочкам вызовов. В отличие от подхода, ориентированного на данные, он не очень дружелюбен к оборудованию.
  • Функции событий каждого MonoBehaviour вызываются индивидуально, и вызовы не обязательно группируются по типу MonoBehaviour. Например, если у вас 1000 монстров MonoBehaviours, каждый монстр будет обновляться отдельно, а не обязательно вместе с другими монстрами.

Объектно-ориентированный стиль обычного C# и многие API Unity обычно приводят к решениям, перегруженным абстракциями. В результате в коде появляются неэффективные элементы, которые трудно выявить и изолировать.

Для кого предназначена электронная книга DOTS?
Предварительный просмотр новой электронной книги "Введение в стек технологий, ориентированных на данные" для продвинутых разработчиков Unity.

Эта электронная книга находится в свободном доступе для всех желающих, но предназначена для разработчиков Unity, которые имеют опыт разработки объектно-ориентированных игр на основе моноповедения, но являются новичками в Unity DOTS и разработке дизайна, ориентированного на данные.

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