内存分配器
Allocator is responsible for managing memory allocation for an application. For example, RAM allocation is required when creating a new node.Allocator负责管理应用程序的内存分配。例如,创建新节点时需要进行RAM分配。
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动态地在堆上分配内存。但是,使用标准分配器可能会导致性能下降:每次分配都需要额外的内存量。换句话说,操作系统存储有关内存分配的数据,这可能会消耗大量RAM。此外,标准系统分配器提供有关内存消耗统计信息的不准确信息。
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.动态池也可以优化性能,但不能优化内存消耗。但是,它们仅受RAM大小的限制,这是一个优点。此外,动态池更灵活,因为它们可以根据需要扩展和缩小它们的大小。
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.除了自定义RAM分配器外,UNIGINE还提供了一个使用内存池管理VRAM分配的选项。
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.默认情况下可分配的最小内存块为64Kb。为了避免为显着较小的图形资源(例如,需要少于64Kb的纹理)分配如此大量的内存,我们需要使用内存池。
- 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.表中的值显示默认堆的统计信息,包括当前VRAM消耗、分配的VRAM量、池中的分配数等。 |
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提供有关RAM和VRAM使用和分配分析的统计信息。要访问此信息,请运行通用分析器并查看以下值:
RAM Allocations StatisticsRAM分配统计#
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).工作集的当前大小。工作集是当前在物理RAM中可见的内存页集(检查源)。 |
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 StatisticsVRAM分配统计#
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使用的VRAM量。此值由图形驱动程序提供。 |
GPU ram usage | The amount of RAM used by GPU. This value is provided by a graphics driver.GPU使用的RAM量。此值由图形驱动程序提供。 |
GPU alloc | The number of allocations made by the engine on GPU.引擎在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.VRAM池的最大大小。 |
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.还有一个单独的统计块,用于跟踪蒙皮网格和贴花的分配。
GPU Allocator skinned | The amount of video memory allocated for skinned meshes.为蒙皮网格分配的显存量。 |
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.场景中的每个蒙皮网格都独立分配内存。蒙皮网格的VRAM在单独的池中以块的形式分配。UNIGINE允许通过skinned_mesh_pool_chunk_size控制台命令配置块的大小。默认情况下,它是64Mb。
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控制台命令。