Systems
Console Commands & Variables
A console command is sent to the engine to execute a specific functionality.
A console variable is a global state in which data is stored and can be modified through the console.
The supported types are int, float and string.
The following table shows the corresponding C++ types, and the methods to obtain the value of a console variable.
Create a Console Variable
Console variables should be created early when the engine starts, to make sure that auto completion in the editor works.
Therefore, the recommended way to declare a console variable is through static variables.
A console variable is declared with the TAutoConsoleVariable
template type and the template argument represents the data type of the variable.
A console variable is created with a name, a default value, a description, and EConsoleVariableFlags
flags.
The flags are defined in IConsoleManager.h
.
static TAutoConsoleVariable<int32> CVar(
TEXT("MyVariable"),
42,
TEXT("A variable"),
ECVF_Cheat);
Consoles variables can also be created by calling the IConsoleManager::RegisterConsoleVariable
function.
The global instance of the console manager is accessed using IConsoleManager.Get()
.
IConsoleManager::Get().RegisterConsoleVariable(
TEXT("MyCVar"),
42,
TEXT("A variable"),
ECVF_Cheat);
Access a Console Variable
The most efficient way to access a console variable is perform a look up with IConsoleManager::FindConsoleVariable
and store the result in a static variable.
As console variables persist during the lifetime of the project, it is safe.
static const auto MyCVar = IConsoleManager::Get().FindConsoleVariable(TEXT("MyCVar"));
int32 Value = MyCVar->GetInt();
Command-Line
The value of console variables can be set when starting the editor using the -ExecCmds
argument.
UE4Editor.exe GAMENAME -ExecCmds="r.MyCvar 42"
Memory Allocators
Allocation Rules
Blocks equal or larger than 16 bytes are 16-byte-aligned.
Blocks smaller than 16 bytes are 8-byte aligned.
Global Allocators
The global allocator is GMalloc
. It is a FMalloc
allocator.
The instance to the global allocator is platform-dependent.
It is accessed using FPlatformMemory::BaseAllocator
.
On most platforms, it returns the ANSI malloc implementation represented by FMallocAnsi
.
FMallocAnsi
performs aligned allocations using a platform-dependent function such as _aligned_malloc
(Microsoft), posix_memalign
(Apple, Linux, Web), or memalign
(PS4).
On platforms that do not provide aligned allocations, the allocation falls back to a regular malloc
call with custom padding.
On some platforms, the default base allocator can be replaced with a different implementation using specific preprocessor symbols or command-line options.
The other allocators are:
- Binned, Binned2
- Binned3 (64-bit only)
- TBB (Windows and macOS)
Containers
There are different allocation policies for containers, represented by allocator traits.
The base template type for traits is TAllocatorTraits
.
It actually derive from the non-template type TAllocatorTraitsBase
.
FHeapAllocator
– Always allocates the elements indirectly.
TAlignedHeapAllocator
– Similar toTHeapAllocator
but supports aligned allocations with anAlignment
parameter.template<uint32 Alignment> TAlignedHeapAllocator< Alignment >
TInlineAllocator
– Allocates up to a specified number of elements in the same allocation as the container, and falls back to a secondary container when the number of inline elements is reached.template<uint32 NumInlineElements, typename SecondaryAllocator> TInlineAllocator< NumInlineElements, SecondaryAllocator >
NumInlineElements
is the number of inline elements.
SecondaryAllocator
is the fall back allocator. By default, it isFDefaultAllocator
.
TFixedAllocator
– Allocates up to a specified number of elements. There is no secondary storage when the number of inline elements is reached.template<uint32 NumInlineElements> TFixedAllocator< NumInlineElements >
TSetAllocator
– Encapsulates the allocators used by a set. By default, it is aTSparseArrayAllocator
.
Low-Level Memory
Memory allocations are tracked by the Low-Level Memory (LLM) Tracker.
Every memory allocation is assigned a tag value identifying the category to which it belongs.
The tags are applied using tag-scope macros.
LLM is stripped out of Shipping builds.
Usage
To enable LLM, launch the project with the -LLM Enables
command-line argument.
To continuously writes out all values to a CSV file, use the -LLMCSV
argument instead.
There are two trackers represented by the ELLMTracker
enumerated type: Default
and Platform
.
The Platform
tracker is used by the platform-dependent modules such as Windows, macOS, Direct3D, Metal, Vulkan, and so on.
There are two corresponding scope macros:
LLM_SCOPE
– Default tracker.
LLM_PLATFORM_SCOPE
– Platfom tracker.
The macros are called with the tag to associate with the allocations.
Tags are represented by the ELLMTag
enumerated type.
Example
In FAssetRegistryModule::StartupModule
, the scope macro is used with the AssetRegistry
tag.
void FAssetRegistryModule::StartupModule()
{
LLM_SCOPE(ELLMTag::AssetRegistry);
...
}
Implementation
LLM maintains a map of all allocations indexed by a pointer.
LLM uses 21 bytes per allocation.
Allocation | Size |
---|---|
Pointer | 8 bytes |
Pointer Hash Key | 4 bytes |
Size | 4 bytes |
Tag | 1 byte |
Hash Map Index | 4 bytes |
The memory used by LLM is managed by the LLMAlloc
and LLMFree
functions.
Add a New Tag
- Add a value to the
ELLMTag
enumerated type inLowLevelMemTracker.h
.
- Add a corresponding element to the
ELLMTagNames
array inLowLevelMemTracker.cpp
.
- Add tag scopes using the
LLM_SCOPE
macro.