🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Creating a custom stack allocator for game engine

Started by
20 comments, last by JoshuaManton 1 year, 10 months ago

Every local variable is allocated on the stack. On extremely rare occasions I've written my own stack allocator. On the other hand I nearly always use custom heap allocation. If you are going to write a custom stack allocator, understand why you need it (or think it's more optimal) first.

Advertisement

Gnollrunner said:
On extremely rare occasions I've written my own stack allocator. On the other hand I nearly always use custom heap allocation. If you are going to write a custom stack allocator, understand why you need it

Now i'm confused, please clarify…

Because i don't think we can allocate anything from the stack at all. Local variables or arrays go to the stack, but any allocation we do goes to the heap. Am i wrong? Are there exceptions for small allocations eventually?

I think the term ‘stack allocator’ relates to the algorithm of using a ‘stack’ to manage allocations, but the memory itself is still on the heap. No?

JoeJ said:
Because i don't think we can allocate anything from the stack at all. Local variables or arrays go to the stack, but any allocation we do goes to the heap. Am i wrong? Are there exceptions for small allocations eventually?

If you allocate with “new”, the allocation goes on the heap. But you can use placement-new to allocate directly in any type of memory. Conceptually, a stack allocator works like this:

void func(void)
{
	char memory[sizeof(Class)];
	
	auto* pClass = new (memory) Class();
	// do something with pClass
}

Now this example isn't exactly practical, but the concept is, that you can allocate a block of memory somewhere (be it on the stack or on the heap), and then you can allocate from that, instead of from the heap. For example, you could allocate one big block of stack-memory before the rendering-pass, and then place all temporary allocations inside that memory.

Oh, that's pretty awesome maybe, regarding something different.

I just had a discussion with physics engine dev. I was complaining that i have to allocate all physics objects individually with new, but what i want is to use arrays of rigid bodies per ragdoll for example.

Maybe, using such trick, i could indeed do this. Need to try… ;D

JoeJ said

Now i'm confused, please clarify…

Because i don't think we can allocate anything from the stack at all. Local variables or arrays go to the stack, but any allocation we do goes to the heap. Am i wrong? Are there exceptions for small allocations eventually?

I think the term ‘stack allocator’ relates to the algorithm of using a ‘stack’ to manage allocations, but the memory itself is still on the heap. No?

Well I guess we are getting hung up on the definition of allocation. Locals are implicitly allocated on the stack assuming they aren't optimized away. Alloca which is non-standard but very common does allocate on the stack however.

Gnollrunner said:

JoeJ said

Now i'm confused, please clarify…

Because i don't think we can allocate anything from the stack at all. Local variables or arrays go to the stack, but any allocation we do goes to the heap. Am i wrong? Are there exceptions for small allocations eventually?

I think the term ‘stack allocator’ relates to the algorithm of using a ‘stack’ to manage allocations, but the memory itself is still on the heap. No?

Well I guess we are getting hung up on the definition of allocation. Locals are implicitly allocated on the stack assuming they aren't optimized away. Alloca which is non-standard but very common does allocate on the stack however.

This is what I meant, a custom heap allocator implemented as a stack

Juliean said:

JoeJ said:
Because i don't think we can allocate anything from the stack at all. Local variables or arrays go to the stack, but any allocation we do goes to the heap. Am i wrong? Are there exceptions for small allocations eventually?

If you allocate with “new”, the allocation goes on the heap. But you can use placement-new to allocate directly in any type of memory. Conceptually, a stack allocator works like this:

void func(void)
{
	char memory[sizeof(Class)];
	
	auto* pClass = new (memory) Class();
	// do something with pClass
}

Now this example isn't exactly practical, but the concept is, that you can allocate a block of memory somewhere (be it on the stack or on the heap), and then you can allocate from that, instead of from the heap. For example, you could allocate one big block of stack-memory before the rendering-pass, and then place all temporary allocations inside that memory.

I wouldnt call what placement new does actual allocation since you can overload operator new and operator placement new in C++. In the first case you are also doing allocation in the later case all you are doing is calling the constructor at a specific memory location.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max, Watch Dogs: Legion

@undefined

bryant5 said:

This is what I meant, a custom heap allocator implemented as a stack

This isn't practical for ever application, but some game programmers seem to swear by it. Basically you just reserve a large chunk of memory and allocate from that by moving a pointer which is initially set at the beginning of that chunk. There is no deallocation, except for throwing the whole thing out at an opportune time (for example between levels). You can optimize this a bit by just reserving a large chunk of virtual memory space, and commiting pages as you need them, instead of allocating everything up front.

Again, whether this is a good strategy or not really depends on the game.

Gnollrunner said:
This isn't practical for ever application, but some game programmers seem to swear by it. … Again, whether this is a good strategy or not really depends on the game.

It was more common 20-25 years ago, especially on consoles. It's still somewhat common pattern to allocate all the memory on a console and then manage it yourself. Back then one side of memory was built as a stack for permanent objects in the game. This eliminates the overhead of tracking the objects, further saving precious memory and reducing overhead. At game start a bunch of systems start up and the allocations will exist for as long as the game runs, never to be deleted/destroyed, so they could just be blindly allocated as a giant block in memory.

You can also build other systems that work with it as a stack in older level-based systems, but it required developers to be quite mindful of when and how objects were created and destroyed.

It is less common these days, but still sometimes done.

Gnollrunner said:

@undefined

bryant5 said:

This is what I meant, a custom heap allocator implemented as a stack

This isn't practical for ever application, but some game programmers seem to swear by it. Basically you just reserve a large chunk of memory and allocate from that by moving a pointer which is initially set at the beginning of that chunk. There is no deallocation, except for throwing the whole thing out at an opportune time (for example between levels). You can optimize this a bit by just reserving a large chunk of virtual memory space, and commiting pages as you need them, instead of allocating everything up front.

Again, whether this is a good strategy or not really depends on the game.

I know it’s not common anymore, just using it as a memory management learning tool ?

This topic is closed to new replies.

Advertisement