Custom Memory Allocator – Arma 3
No edit summary |
No edit summary |
||
Line 10: | Line 10: | ||
The allocator is a dll placed in a directory named "dll" located next to the game executable. Allocator search order is: | The allocator is a dll placed in a directory named "dll" located next to the game executable. Allocator search order is: | ||
* tbb4malloc_bi - based on [http://threadingbuildingblocks.org Intel TBB 4], distributed under [https://www.apache.org/licenses/LICENSE-2.0 Apache 2.0] + [http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt01ch01s02.html RE] ([ | * tbb4malloc_bi - based on [http://threadingbuildingblocks.org Intel TBB 4], distributed under [https://www.apache.org/licenses/LICENSE-2.0 Apache 2.0] + [http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt01ch01s02.html RE] ([https://github.com/BohemiaInteractive/TBB4 source code]) based on [https://www.threadingbuildingblocks.org/download#stable_releases tbb2017_20160916oss] | ||
* jemalloc_bi - based on [http://www.canonware.com/download/jemalloc/ JEMalloc], distributed under [http://www.canonware.com/jemalloc/license.html BSD-derived license source code] ([http://downloads.bistudio.com/arma3.com/allocs/JEMalloc_source.7z source code]) based on [http://www.canonware.com/download/jemalloc/jemalloc-4.2.1.tar.bz2 jemalloc-4.2.1.tar.bz2] | * jemalloc_bi - based on [http://www.canonware.com/download/jemalloc/ JEMalloc], distributed under [http://www.canonware.com/jemalloc/license.html BSD-derived license source code] ([http://downloads.bistudio.com/arma3.com/allocs/JEMalloc_source.7z source code]) based on [http://www.canonware.com/download/jemalloc/jemalloc-4.2.1.tar.bz2 jemalloc-4.2.1.tar.bz2] | ||
* customMalloc_bi - not provided, feel free to plug-in your own | * customMalloc_bi - not provided, feel free to plug-in your own |
Revision as of 15:58, 16 January 2017
The memory allocator is a very important component, which significantly affects both performance an stability of the game. The purpose of is to allow the allocator to be developed independently on the application, allowing both Bohemia Interactive and community to fix bugs and improve performance without having to modify the core game files.
Default
Default allocator used by the engine is based on Intel TBB 4 (see details about tbb4malloc_bi below)
Specifying a custom allocator
The allocator is a dll placed in a directory named "dll" located next to the game executable. Allocator search order is:
- tbb4malloc_bi - based on Intel TBB 4, distributed under Apache 2.0 + RE (source code) based on tbb2017_20160916oss
- jemalloc_bi - based on JEMalloc, distributed under BSD-derived license source code (source code) based on jemalloc-4.2.1.tar.bz2
- customMalloc_bi - not provided, feel free to plug-in your own
If no allocator dll is found, functions _aligned_malloc/ _aligned_free (using Windows Heap functions) are used as a fallback note: Windows 7 allocator seems to be quite good, and it may therefore make sense for some users to delete all custom allocators on Windows 7 or newer).
You can select an allocator by via commandline below or deleting other allocators from the \dll\ folder.
Commandline parameter
You can specify a particular allocator from a command line, like:
- -malloc=tbb4malloc_bi
- -malloc=jemalloc_bi
or
- -malloc=mybestmalloc_bi
- -malloc=system can be used to force using Windows allocator even when allocator dlls are present
(dll directory and extension are appended automatically, the allocator must not be located in other directory and its name must not contain any dots before the .dll extension)
There is another malloc (currently experimental) that try to use Large Pagefile instead of Small Pagesize: Fred41's tbbMalloc
Dedicated server
You can specify allocator for Windows dedicated server the same way as for client binary,
with specifically adjusted memory allocator you may experience performance gains,
for example with Large Pages support or ability define huge pre-allocation memory regions to lessen allocation load
Linux dedicated server uses allocator provided by operating system. There are NO plans to allow its customization yet.
DLL Interface
The dll interface is as follows:
extern "C" {
__declspec(dllexport) size_t __stdcall MemTotalCommitted(); // _MemTotalCommitted@0
__declspec(dllexport) size_t __stdcall MemTotalReserved(); // _MemTotalReserved@0
__declspec(dllexport) size_t __stdcall MemFlushCache(size_t size); // _MemFlushCache@4
__declspec(dllexport) void __stdcall MemFlushCacheAll(); // _MemFlushCacheAll@0
__declspec(dllexport) size_t __stdcall MemSize(void *mem); // _MemSize@4
__declspec(dllexport) void *__stdcall MemAlloc(size_t size); // _MemAlloc@4
__declspec(dllexport) void __stdcall MemFree(void *mem); // _MemFree@4
__declspec(dllexport) size_t __stdcall MemSizeA(void *mem, size_t alignment); // _MemSizeA@8
__declspec(dllexport) void *__stdcall MemAllocA(size_t size, size_t alignment); // _MemAllocA@8
__declspec(dllexport) void __stdcall MemFreeA(void *mem); // _MemFreeA@4
};
Note: besides of the interface above, if the allocator is performing any per-thread caching, it will typically want to perform a cleanup of per-thread data on DLL_THREAD_DETACH event sent to DllMain function.
MemTotalCommitted()
Total memory committed by the allocator (should correspond to VirtualAlloc with MEM_COMMIT)
MemTotalReserved()
Total memory reserved by the allocator (should correspond to VirtualAlloc with MEM_RESERVE)
MemFlushCache(size_t size)
Try to flush at least "size" bytes of memory from caches and working areas, return how much memory was flushed. Called by game when memory needs to be trimmed to reduce virtual memory use.
MemFlushCacheAll()
Flush all memory held in caches and working areas. Called by game when memory needs to be trimmed to reduce virtual memory use.
MemSize(void *mem)
Return allocated size of given memory block.
MemAlloc(size_t size)
Allocate at least size bytes of memory, return the allocated memory. If the size is 16 B or more, the memory must be 16 B -aligned, so that it is usable to hold SSE data.
MemFree(void *mem)
Free given memory block.
MemSizeA(void *mem, size_t alignment)
Return allocated size of given memory block allocated via MemAllocA. Aligment must be the same as when MemAllocA was called.
MemAllocA(size_t size, size_t alignment)
Allocate at least size bytes of memory, return the allocated memory aligned to "aligment" bytes.
MemFreeA(void *mem)
Free a given memory block allocated via MemAllocA.