This page has been translated automatically.
Видеоуроки
Интерфейс
Основы
Продвинутый уровень
Подсказки и советы
Основы
Программирование на C#
Рендеринг
Профессиональный уровень (SIM)
Принципы работы
Свойства (properties)
Компонентная Система
Рендер
Режимы вывода изображения
Физика
Браузер SDK 2
Лицензирование и типы лицензий
Дополнения (Add-Ons)
Демонстрационные проекты
API Samples
Редактор UnigineEditor
Обзор интерфейса
Работа с ассетами
Контроль версий
Настройки и предпочтения
Работа с проектами
Настройка параметров ноды
Setting Up Materials
Настройка свойств
Освещение
Sandworm
Использование инструментов редактора для конкретных задач
Расширение функционала редактора
Встроенные объекты
Ноды (Nodes)
Объекты (Objects)
Эффекты
Декали
Источники света
Geodetics
World-ноды
Звуковые объекты
Объекты поиска пути
Player-ноды
Программирование
Основы
Настройка среды разработки
Примеры использования
C++
C#
UnigineScript
Унифицированный язык шейдеров UUSL (Unified UNIGINE Shader Language)
Плагины
Форматы файлов
Материалы и шейдеры
Rebuilding the Engine Tools
Интерфейс пользователя (GUI)
Двойная точность координат
API
Animations-Related Classes
Containers
Common Functionality
Controls-Related Classes
Engine-Related Classes
Filesystem Functionality
GUI-Related Classes
Math Functionality
Node-Related Classes
Objects-Related Classes
Networking Functionality
Pathfinding-Related Classes
Physics-Related Classes
Plugins-Related Classes
IG Plugin
CIGIConnector Plugin
Rendering-Related Classes
VR-Related Classes
Работа с контентом
Оптимизация контента
Материалы
Визуальный редактор материалов
Material Nodes Library
Miscellaneous
Input
Math
Matrix
Textures
Art Samples
Учебные материалы

Аллокатор памяти

Allocator отвечает за управление выделением памяти для приложения. Например, выделение оперативной памяти требуется при создании новой ноды.

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

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

Примечание
Аллокатор UNIGINE собирает статистику для небольших выделений, поскольку утечки памяти в основном происходят при небольших выделениях размером до 4000 байт. Чтобы проверить статистику, запустите консольную команду memory_info.

Пулы памяти#

Пользовательский аллокатор UNIGINE предоставляет два основных пула памяти для распределения: статический и динамический.

  • Статический пул выделяется только один раз при запуске двигателя и не может быть изменен.
  • Динамический пул динамически увеличивается и вступает в игру, когда память, выделенная в статическом пуле, заполнена.
Примечание
Может быть несколько пулов каждого типа. Размер пула всегда кратен 16.

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

Статический пул#

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

Настройка статических пулов#

Статические пулы ограничены значениями размера, которые вы должны указать заранее. Для этого вам необходимо знать объем требуемой памяти и ее расположение. Проще говоря, вам нужно знать, какой объем памяти каждого типа (16, 32, 48 байт и т.д.) следует выделить. Например, на рисунке ниже показаны четыре статических пула, которые содержат аллокации объемом 16, 32, 48 и 64 байта:

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

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

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

В целом, процесс выглядит следующим образом:

  1. В своем проекте определите место, для которого требуется значительный объем памяти.
  2. Настройте свой проект так, чтобы он начинался с этого места.
  3. Запустите приложение с параметром командной строки -memory_statistics_enabled 1. Это позволит собирать статистику по памяти, необходимую для настройки пула.
    Примечание
    Статистика собирается только в том случае, если ранее не были настроены статические пулы.
  4. В консоли запустите консольную команду memory_optimize_static_pools, чтобы обновить и оптимизировать статические пулы.
  5. Сразу после этого запустите консольную команду boot_config_save, чтобы сохранить настройки статических пулов в файл конфигурации .bootдля использования при следующем запуске приложения.
  6. Перезапустите приложение, чтобы использовать обновленные конфигурации статического пула.
Примечание
Статические пулы не могут функционировать, если лимиты превышены. В таких случаях активируются динамические пулы.

Динамический пул#

Примечание
Динамические пулы недоступны на Linux.

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

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

Настройка динамических пулов#

Каждый динамический пул хранит аллокации определенного типа - 16, 32, 48 байт и т.д. Таким образом, вы всегда можете проверить, сколько памяти каждого типа выделено в динамических пулах. Эти значения всегда кратны 16. Например, на рисунке ниже представлено 16 пулов разных размеров:

Чтобы настроить динамические пулы, вы можете использовать консольную команду memory_dynamic_pool. Она определяет количество динамических пулов, указывая максимальный размер выделений. По умолчанию этот размер равен 256 байтам, что означает, что существует 16 пулов, содержащих выделения размером от 16 до 256 байт.

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

Анализ статистики пулов#

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

Он отображает статистику по небольшим выделениям в виде таблицы, где каждая строка соответствует одному пулу памяти.

Распределение статических пулов

  • Первое значение указывает тип распределений, хранящихся в пуле.
  • Второе значение отображает текущее распределение памяти в пуле.
  • Третье значение представляет собой максимальное потребление памяти, которое произошло в пуле. Это значение указывает максимальный объем памяти, запрошенный движком (пиковое потребление).
  • Четвертое значение указывает на начальное выделение памяти при запуске движка, которое определяет максимальный объем памяти, который движок может использовать из пула.
  • Пятое значение представляет собой накладные расходы на оперативную память, необходимые для обслуживания пула.
  • Шестое значение указывает на текущее количество произведенных распределений в миллионах.
Распределение динамических пулов

  • Первое значение указывает тип распределений, хранящихся в пуле.
  • Второе значение указывает, сколько выделений удерживается в пуле для дальнейшего использования. Это значение ограничено 2 Мб.
  • Третье значение отображает количество свободных аллокаций в пуле.
Общий объем аллокаций

Значения в таблице предоставляют статистику по всем распределениям памяти, которые произошли во всех пулах

Распределение видеопамяти#

В дополнение к пользовательскому аллокатору оперативной памяти UNIGINE предоставляет возможность управления распределением видеопамяти с помощью пулов памяти.

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

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

  • Минимальный объем памяти, который может быть выделен по умолчанию, составляет 64 Кб. Чтобы избежать выделения такого большого объема памяти для графических ресурсов значительно меньшего размера (например, текстур, для которых требуется гораздо меньше 64 Кб), нам необходимо использовать пулы памяти.
  • Процесс выделения происходит крайне медленно, поэтому нам приходится выделять видеопамять заранее, а затем распределять ее по мере необходимости.
Примечание
Распределение видеопамяти включено по умолчанию.

Настройка пулов#

Существуют консольные команды, которые позволяют настраивать пулы для выделения видеопамяти:

d3d12_small_pool_enabledФайл конфигурации: *.boot
Описание:
  • Позволяет включать и выключать выделение небольших пулов. По умолчанию выделение включено. Однако вы можете отключить его с помощью консоли, сохранить файл конфигурации .boot и перезапустить приложение, чтобы применить изменения.
d3d12_small_pool_sizeФайл конфигурации: *.boot
Описание:
  • Устанавливает максимальный размер пула в килобайтах.
d3d12_small_pool_chunk_sizeФайл конфигурации: *.boot
Описание:
  • Указывает минимальный размер блока памяти, который может быть выделен, в килобайтах. Размер блока будет равен или больше этого значения.

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

Анализ статистики пулов#

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

Примечание
Количество пулов может варьироваться в зависимости от используемой видеокарты.
Heap Default Значения в таблице отображают статистику по куче по умолчанию, включая текущее потребление видеопамяти, объем выделенной видеопамяти, количество выделений в пуле и так далее.
Heap Upload Значения в таблице отображают статистику по куче, используемой для загрузки.
Heap Readback Значения в таблице отображают статистику по куче, используемой для обратного считывания.

Для получения более подробной информации, пожалуйста, обратитесь к этой статье.

Профилирование аллокаций#

UNIGINE предоставляет статистические данные об использовании оперативной и видеопамяти и профилировании аллокаций. Чтобы получить доступ к этой информации, запустите Generic Performance Profiler и посмотрите на следующие значения:

Примечание
Статистика будет отличаться в зависимости от операционной системы.

Статистика распределения оперативной памяти#

CPU ram free Объем доступной в данный момент памяти.
CPU ram usage physics Текущий размер рабочего набора. Рабочий набор - это набор страниц памяти, которые в данный момент отображаются в физической оперативной памяти (смотрите в источнике).
CPU ram usage committed Общий объем частной памяти, выделенный менеджером памяти для запущенного процесса (смотрите в источнике).
CPU ram malloc Объем памяти, выделяемый пользовательским аллокатором UNIGINE.
CPU ram static pool Объем памяти, выделяемый в статических пулах.
CPU ram dynamic pool Объем памяти, выделяемый в динамических пулах. Доступно только в Windows.
CPU ram instance pool Объем памяти, выделяемый в пулах экземпляров.
Frame Allocations Количество аллокаций, выполненных для каждого кадра.
Live Allocations Текущее/максимальное количество аллокаций, выполненных во время выполнения (пиковое потребление).

Статистика распределения видеопамяти#

GPU vram free Объем доступной в данный момент видеопамяти.
GPU vram usage Объем видеопамяти, используемый графическим процессором. Это значение задается графическим драйвером.
GPU ram usage Объем оперативной памяти, используемый графическим процессором. Это значение задается графическим драйвером.
GPU alloc Количество аллокаций, выполненных движком на графическом процессоре.
GPU Frame Allocations Количество выделяемой видеопамяти для каждого кадра.
GPU Live Allocations Текущее/максимальное количество аллокаций, выполненных во время выполнения (пиковое потребление).
GPU Allocator small pool size Максимальный размер пула видеопамяти.
GPU Allocator small usage Фактическое использование пула видеопамяти.

Существует также отдельный блок статистики, который отслеживает распределение памяти для Skinned Mesh и декалей.

GPU Allocator skinned Объем видеопамяти, выделенный для Skinned Mesh.
GPU Allocator decals Объем видеопамяти, выделенный для декалей.

Память выделяется независимо для каждого Skinned Mesh в сцене. Видеопамять для Skinned Mesh выделяется отдельными блоками в отдельном пуле. UNIGINE позволяет настраивать размер блоков с помощью консольной команды skinned_mesh_pool_chunk_size. По умолчанию этот размер составляет 64 Мб.

Примечание
Чем больше размер блока, тем выше производительность Skinned Mesh.

То же самое касается и декалей. Чтобы настроить размер блока для декалей, используйте консольную команду decal_pool_chunk_size.

Последнее обновление: 05.09.2024
Build: ()