Аллокатор памяти
Allocator is responsible for managing memory allocation for an application. For example, RAM allocation is required when creating a new node.Allocator отвечает за управление выделением памяти для приложения. Например, выделение оперативной памяти требуется при создании новой ноды.
By default, a standard system malloc dynamically allocates memory on the heap. However, using the standard allocator may result in performance drop: each allocation requires an additional amount of memory. In other words, the operating system stores data about memory allocations, and this can consume large amount of RAM. Moreover, the standard system allocator provides inaccurate information regarding statistics on memory consumption.По умолчанию стандартная системная функция malloc динамически выделяет память в куче. Однако использование стандартного аллокатора может привести к снижению производительности: для каждого выделения требуется дополнительный объем памяти. Другими словами, операционная система хранит данные о распределении памяти, и это может занять большой объем оперативной памяти. Кроме того, стандартный системный аллокатор предоставляет неточную информацию о статистике потребления памяти.
That is why UNIGINE provides a custom allocator in addition to a standard system malloc. It allocates memory in pools, making the allocation process faster and more efficient. Also, it enables gathering statistics on memory consumption, including information on the total number of allocations and the number of allocations per frame.Вот почему UNIGINE в дополнение к стандартной системе malloc предоставляет пользовательский аллокатор. Он выделяет память в пулы, что ускоряет и повышает эффективность процесса выделения памяти. Кроме того, он позволяет собирать статистику о потреблении памяти, включая информацию об общем количестве выделений и количестве выделений на кадр.
Memory PoolsПулы памяти#
The UNIGINE custom allocator provides two main memory pools for allocations: static and dynamic.Пользовательский аллокатор UNIGINE предоставляет два основных пула памяти для распределения: статический и динамический.
- The static pool is allocated only once on the engine start-up and cannot be changed.Статический пул выделяется только один раз при запуске двигателя и не может быть изменен.
- The dynamic pool increases dynamically and comes into play when the memory allocated in the static pool is full.Динамический пул динамически увеличивается и вступает в игру, когда память, выделенная в статическом пуле, заполнена.
There are also additional instance pools that store allocations defined by developers. Usually, these are the allocations which are required regularly. They work the same way as the dynamic pools, but the instance pools have no size limitation.Существуют также дополнительные пулы экземпляров, в которых хранятся все ресурсы, определенные разработчиками. Как правило, это те ресурсы, которые требуются регулярно. Они работают так же, как и динамические пулы, но у пулов экземпляров нет ограничений по размеру.
Static PoolСтатический пул#
The static pools are essential for optimizing memory consumption. In other words, each allocation consumes approximately zero additional memory when using the static pools. Additionaly, it optimizes the allocations themselves, making them faster.Статические пулы необходимы для оптимизации потребления памяти. Другими словами, при использовании статических пулов аллокации практически не требуют дополнительной памяти. Кроме того, это оптимизирует сами аллокации, ускоряя их.
Configuring Static PoolsНастройка статических пулов#
The static pools are limited by the size values you should specify in advance. To do so, you need to know the amount of required memory and its layout. To put it simply, you need to know how much memory of each type (16, 32, 48 bytes, etc.) to allocate. For example, the picture below demonstrates four static pools that contain allocations of 16, 32, 48, and 64 bytes:Статические пулы ограничены значениями размера, которые вы должны указать заранее. Для этого вам необходимо знать объем требуемой памяти и ее расположение. Проще говоря, вам нужно знать, какой объем памяти каждого типа (16, 32, 48 байт и т.д.) следует выделить. Например, на рисунке ниже показаны четыре статических пула, которые содержат аллокации объемом 16, 32, 48 и 64 байта:
Configuration of the static pools should be done for the specific hardware that corresponds to the minimum specifications. The static pool settings are stored in the .boot configuration file.Статические пулы должны настраиваться под конкретное оборудование, соответствующее минимальным спецификациям. Настройки статического пула хранятся в файле конфигурации .boot.
In general, the process is as follows:В целом, процесс выглядит следующим образом:
- In your project, identify a location that demands a significant amount of memory.В своем проекте определите место, для которого требуется значительный объем памяти.
- Set up your project so that it starts with this location.Настройте свой проект так, чтобы он начинался с этого места.
- Run the application with the -memory_statistics_enabled 1 command line option. It will enable gathering memory statistics required for pool configuration.
The statistics are collected only if there are no static pools configured before.Запустите приложение с параметром командной строки -memory_statistics_enabled 1. Это позволит собирать статистику по памяти, необходимую для настройки пула.The statistics are collected only if there are no static pools configured before.The statistics are collected only if there are no static pools configured before.The statistics are collected only if there are no static pools configured before.Статистика собирается только в том случае, если ранее не были настроены статические пулы.
- In the console, run the memory_optimize_static_pools console command to update and optimize the static pools.В консоли запустите консольную команду memory_optimize_static_pools, чтобы обновить и оптимизировать статические пулы.
- Right after that, run the boot_config_save console command to save the static pools settings to the .boot configuration file so that they can be used on the next application launch.Сразу после этого запустите консольную команду boot_config_save, чтобы сохранить настройки статических пулов в файл конфигурации .bootдля использования при следующем запуске приложения.
- Restart the application to use the updated static pool configurations.Перезапустите приложение, чтобы использовать обновленные конфигурации статического пула.
Dynamic PoolДинамический пул#
The dynamic pools also can optimize performance, but they cannot optimize memory consumption. However, they are restricted only by the size of RAM, which is an advantage. Moreover, the dynamic pools are more flexible as they can both expand and shrink their size as needed.Динамические пулы также могут оптимизировать производительность, но они не могут оптимизировать потребление памяти. Однако они ограничены только объемом оперативной памяти, что является преимуществом. Кроме того, динамические пулы более гибкие, поскольку могут как расширяться, так и уменьшаться по мере необходимости.
Configuring Dynamic PoolsНастройка динамических пулов#
Each dynamic pool stores allocations of a certain type — 16, 32, 48 bytes allocations, etc. So, you can always check how much memory of each type is allocated in the dynamic pools. These values are always a multiple of 16. For example, in the picture below, there are 16 pools of different sizes:Каждый динамический пул хранит аллокации определенного типа - 16, 32, 48 байт и т.д. Таким образом, вы всегда можете проверить, сколько памяти каждого типа выделено в динамических пулах. Эти значения всегда кратны 16. Например, на рисунке ниже представлено 16 пулов разных размеров:
To configure the dynamic pools, you can use the memory_dynamic_pool console command. It defines the number of the dynamic pools by specifying the maximum size of allocations. By default, it is set to 256 bytes, which means that there are 16 pools containing allocations from 16 to 256 bytes in size.Чтобы настроить динамические пулы, вы можете использовать консольную команду memory_dynamic_pool. Она определяет количество динамических пулов, указывая максимальный размер выделений. По умолчанию этот размер равен 256 байтам, что означает, что существует 16 пулов, содержащих выделения размером от 16 до 256 байт.
Analyzing Pools StatisticsАнализ статистики пулов#
To get information on all the allocated static and dynamic memory pools, use the memory_info console command.Чтобы получить информацию обо всех выделенных статических и динамических пулах памяти, используйте консольную команду memory_info.
It displays statistics on small allocations as a table, where each row corresponds to one memory pool.Он отображает статистику по небольшим выделениям в виде таблицы, где каждая строка соответствует одному пулу памяти.
Static pools allocations Распределение статических пулов |
|
Dynamic pools allocations Распределение динамических пулов |
|
Total allocations Общий объем аллокаций |
The values in the table provides statistics on all memory allocations that have occurred in all the pools Значения в таблице предоставляют статистику по всем распределениям памяти, которые произошли во всех пулах |
Video Memory AllocationsРаспределение видеопамяти#
In addition to the custom RAM allocator, UNIGINE provides an option for managing VRAM allocations using memory pools.В дополнение к пользовательскому аллокатору оперативной памяти UNIGINE предоставляет возможность управления распределением видеопамяти с помощью пулов памяти.
There are at least two reasons for using video memory allocations:Существует как минимум две причины для выделения видеопамяти:
- The minimum block of memory that can be allocated by default is 64 Kb. To avoid allocating such a large amount of memory for significantly smaller graphic resources (for example, textures that require much less than 64 Kb), we need to use memory pools.Минимальный объем памяти, который может быть выделен по умолчанию, составляет 64 Кб. Чтобы избежать выделения такого большого объема памяти для графических ресурсов значительно меньшего размера (например, текстур, для которых требуется гораздо меньше 64 Кб), нам необходимо использовать пулы памяти.
- The process of allocation is extremely slow, so we have to allocate video memory in advance and then distribute it as needed.Процесс выделения происходит крайне медленно, поэтому нам приходится выделять видеопамять заранее, а затем распределять ее по мере необходимости.
Configuring PoolsНастройка пулов#
There are console commands that allow you to configure the pools for video memory allocations:Существуют консольные команды, которые позволяют настраивать пулы для выделения видеопамяти:
Файл конфигурации: | |
---|---|
Описание:
| |
Файл конфигурации: | |
Описание:
| |
Файл конфигурации: | |
Описание:
|
When configuring chunk sizes, a balance must be found between spikes, performance, and memory consumption. The larger the chunk size, the more stable the frame rate and performance, but the greater the memory consumption. So, we recommend running tests and fine-tuning the values.При настройке размеров блока необходимо найти баланс между скачками, производительностью и потреблением памяти. Чем больше размер блока, тем стабильнее частота кадров и производительность, но тем больше потребление памяти. Поэтому мы рекомендуем выполнить проверку для точной настройки значений.
Analyzing Pools StatisticsАнализ статистики пулов#
To get information on all the allocated video memory pools, use the video_memory_info console command. It will provide you with the following information:Чтобы получить информацию обо всех выделенных пулах видеопамяти, используйте консольную команду video_memory_info. Она предоставит вам следующую информацию:
Heap Default | The values in the table display statistics on the default heap, including the current VRAM consumption, the amount of allocated VRAM, the number of allocations in the pool, and so on.Значения в таблице отображают статистику по куче по умолчанию, включая текущее потребление видеопамяти, объем выделенной видеопамяти, количество выделений в пуле и так далее. |
Heap Upload | The values in the table display statistics on the heap used for uploading.Значения в таблице отображают статистику по куче, используемой для загрузки. |
Heap Readback | The values in the table display statistics on the heap used for reading back.Значения в таблице отображают статистику по куче, используемой для обратного считывания. |
For more details, please refer to this article.Для получения более подробной информации, пожалуйста, обратитесь к этой статье.
Profiling AllocationsПрофилирование аллокаций#
UNIGINE provides statistics on RAM and VRAM usage and allocation profiling. To get access to this information, run the Generic Performance Profiler and take a look at the following values: UNIGINE предоставляет статистические данные об использовании оперативной и видеопамяти и профилировании аллокаций. Чтобы получить доступ к этой информации, запустите Generic Performance Profiler и посмотрите на следующие значения:
RAM Allocations StatisticsСтатистика распределения оперативной памяти#
CPU ram free | The amount of currently available memory.Объем доступной в данный момент памяти. |
CPU ram usage physics | The current size of the working set. The working set is the set of memory pages currently visible in physical RAM (check the source).Текущий размер рабочего набора. Рабочий набор - это набор страниц памяти, которые в данный момент отображаются в физической оперативной памяти (смотрите в источнике). |
CPU ram usage committed | The total amount of private memory that the memory manager has committed for a running process (check the source).Общий объем частной памяти, выделенный менеджером памяти для запущенного процесса (смотрите в источнике). |
CPU ram malloc | The amount of memory allocated by the UNIGINE custom allocator.Объем памяти, выделяемый пользовательским аллокатором UNIGINE. |
CPU ram static pool | The amount of memory allocated in static pools.Объем памяти, выделяемый в статических пулах. |
CPU ram dynamic pool | The amount of memory allocated in dynamic pools. Available on Windows only.Объем памяти, выделяемый в динамических пулах. Доступно только в Windows. |
CPU ram instance pool | The amount of memory allocated in instance pools.Объем памяти, выделяемый в пулах экземпляров. |
Frame Allocations | The number of allocations made per frame.Количество аллокаций, выполненных для каждого кадра. |
Live Allocations | The current/maximum number of allocations made during runtime (peak consumption).Текущее/максимальное количество аллокаций, выполненных во время выполнения (пиковое потребление). |
VRAM Allocations StatisticsСтатистика распределения видеопамяти#
GPU vram free | The amount of currently available video memory.Объем доступной в данный момент видеопамяти. |
GPU vram usage | The amount of VRAM used by GPU. This value is provided by a graphics driver.Объем видеопамяти, используемый графическим процессором. Это значение задается графическим драйвером. |
GPU ram usage | The amount of RAM used by GPU. This value is provided by a graphics driver.Объем оперативной памяти, используемый графическим процессором. Это значение задается графическим драйвером. |
GPU alloc | The number of allocations made by the engine on GPU.Количество аллокаций, выполненных движком на графическом процессоре. |
GPU Frame Allocations | The number of video memory allocations made per frame.Количество выделяемой видеопамяти для каждого кадра. |
GPU Live Allocations | The current/maximum number of allocations made during runtime (peak consumption).Текущее/максимальное количество аллокаций, выполненных во время выполнения (пиковое потребление). |
GPU Allocator small pool size | The maximum size of the VRAM pool.Максимальный размер пула видеопамяти. |
GPU Allocator small usage | Actual usage of the video memory pool.Фактическое использование пула видеопамяти. |
There is also a separate statistics block that tracks allocations for skinned meshes and decals.Существует также отдельный блок статистики, который отслеживает распределение памяти для Skinned Mesh и декалей.
GPU Allocator skinned | The amount of video memory allocated for skinned meshes.Объем видеопамяти, выделенный для Skinned Mesh. |
GPU Allocator decals | The amount of video memory allocated for Decals.Объем видеопамяти, выделенный для декалей. |
Each skinned mesh in the scene allocates memory independently. The VRAM for a skinned mesh is allocated in chunks within a separate pool. UNIGINE allows for configuring the size of the chunks via the skinned_mesh_pool_chunk_size console command. By default, it is 64 Mb.Память выделяется независимо для каждого Skinned Mesh в сцене. Видеопамять для Skinned Mesh выделяется отдельными блоками в отдельном пуле. UNIGINE позволяет настраивать размер блоков с помощью консольной команды skinned_mesh_pool_chunk_size. По умолчанию этот размер составляет 64 Мб.
The same goes with the decals. To configure the chunk size for the decals, use the decal_pool_chunk_size console command.То же самое касается и декалей. Чтобы настроить размер блока для декалей, используйте консольную команду decal_pool_chunk_size.