Dynamic memory allocation in game
Custom dynamic memory allocation is need in game or game engine because:
1. Dynamic memory allocation via malloc() or C++’s global operator new is a very slow operation.
2. On modern CPUs, the performance of a piece of soft ware is oftendominated by its memory access patt erns .
Here are some common kinds of custom allocator
Stack-Based Allocators
A stack allocator is very easy to implement. We simply allocate a large contiguous
block of memory for memory stack . A pointer to the top of the stack is maintained.
All memory addresses below this pointer are considered to be in use, and all
addresses above it are considered to be free. The top pointer is initialized to
the lowest memory address in the stack. Each allocation request simply moves
the pointer up by the requested number of bytes. The most-recently allocated
block can be freed by simply moving the top pointer back down by the size
of the block.
pros:
Easy to implement, won't suffer from memory fragment, because you can only
free the most top memory. So the free memory will always be contiguous.
cons:
You can only free most top memory.
Double-Ended Stack Allocators
allocates up from the bott om of the block and one which allocates down from
the top of the block.
Pool Allocators
A pool allocator works by preallocating a large block of memory whose
size is an exact multiple of the size of the elements that will be allocated.
It always allocate sizeof(element).
pros:
won't suffer from memory fragment, because the hole is always the same size
as the element.
Aligned Allocations
Just like memory pad in class member attribute.
pros:
memory alignment.
cons:
suffer from memory fragment.
Single-Frame Allocations
A single-frame allocator is implemented by reserving a block of memory and
managing it with a simple stack allocator as described above. At the beginning
of each frame, the stack’s “top” pointer is cleared to the bott om of the memory
block.
pros:
Don't have to free memory, it's freed at started of every frame.
Double-Buffered Allocators
A double-buff ered allocator allows a block of memory allocated on frame i to
be used on frame (i + 1).To accomplish this, we create two single-frame stack
allocators of equal size and then ping-pong between them every frame.
pros:
This kind of allocator is extremely useful for caching the results of asynchronous
processing (only for the next frame of course).
About Memory Fragment
When differently-sized objects are being allocated and freed in a random order,
neither a stack-based allocator nor a pool-based allocator can be used. In
such cases, fragmentation can be avoided by periodically defragmenting the
heap. Defragment will cause pointer relocation.
Handler will don't suffer from defragment, because they and just an index into
a non-relocatable table which itself contains the pointers, defragment only
change pointer address in this table.
We can use smart pinter to handle defragment. One approach is to
arrange for all smart pointers to add themselves to a global linked list. Whenever
a block of memory is shift ed within the heap, the linked list of all smart
pointers can be scanned, and each pointer that points into the shift ed block of
memory can be adjusted appropriately.