@mhagain Do you have any control access to this, to ensure that a function using a portion of the scratch buffer won't get corrupted by calling another function which decides to use it?
Or is it only used when interacting with external API's that require such space?
Not answering for mhagain, but I'll butt in with my experiences
When I worked on PS2, we put almost everything
into stack based scratch buffers (mark&release / stack allocators) -- these kinds of allocators outperform almost every other option (allocation is basically just a "+="
To manage them, allocations were added to a stack, and the only way to release anything was to clear the entire
stack. As primitive as it sounds, once you start using such a system, it can be quite easy and powerful.
We had several different stacks with different lifetimes, e.g. there might be one with no guarantees (use/clear as a static scratch space
), one for per-frame temporaries, and others associated to geographical areas of the game (which would be cleared/initialized by the world-streaming system).
In my current engine, I use something similar to Dice's scope-stacks
to manage all engine allocations (global new/malloc type allocations are banned - you must specify from where you are obtaining your memory
); the concepts presented by Dice allow you to reconcile such a simple allocator with C++ features (constructors/destructors) and manage lifetimes in a sensible and predictable way (with much more flexibility than the above ps2 anecdote
If you need some scratch-space in a function, you can create a local "allocation scope", and allocate (quick "+="
) whatever data you want from it. When the function returns, the local "allocation scope" variable goes out of scope and unwinds the stack-allocator back to where it was before the function began (and if necessary, calls any required destructors
Having used this allocation strategy for a while, I feel the same joy as I did when first discovering RAII for the first time -- it's an amazingly simple idea with major power that greatly simplifies my code and reduces memory related bugs.
Unfortunately the gameplay code (i.e. the Lua VM
) still makes heavy use of a general purpose allocator like malloc (thousands of dynamic allocations per frame
), though it's still not really a bottleneck.