3
\$\begingroup\$

I recently read this answer on this site, which says the following:

making sure no allocation/deallocation is being done while the game is running is a golden rule of thumb.

I interpret this as meaning that you should do all the necessary heap allocation while the game is booting up, and arrange it in object pools that you then manage when the game is running. Is this statement correct? The reason I'm struggling to understand it is because I thought that that goes against one of the main reasons we use dynamic heap allocation in games.

That I know of, there are three main uses for using dynamic allocation on the heap:

  1. You have data whose size cannot be know at compile time and needs to be dynamically allocated at runtime.
  2. You need to store objects that take up a large amount of space and won't fit on the stack
  3. You have data whose lifetime outlives the current scope and thus must be stored on the heap.

I was under the impression that one of the main reasons for heap storage being used in games was reason 1, that you can't know the size of data collections beforehand and therefore need to work with dynamic memory. But if all the heap data should be allocated while the game is booting up, then that can't be true.

So does this mean that the reason we use heap storage in games is actually just reason 2 and 3?

\$\endgroup\$
1
  • \$\begingroup\$ I don't see a contradiction between point 1 and the advice to allocate everything at start-up. Start-up is not compile time, so at this stage we can potentially glean how much space we will need by say inspecting our asset and configuration files. We can also revise these allocations during loading sequences, where a hitch due to memory reallocation won't negatively impact gameplay. \$\endgroup\$
    – DMGregory
    Nov 20, 2021 at 14:19

1 Answer 1

2
\$\begingroup\$

I interpret this as meaning that you should do all the necessary heap allocation while the game is booting up, and arrange it in object pools that you then manage when the game is running. Is this statement correct?

Whenever you read that there is a "golden rule" which should "always" be followed, you should raise an eyebrow. Software engineering is more of an art than a science. Even the most recommended best practice is only the best course of action most of the time.

Allocating and deallocating memory a lot while the game is running can have a performance cost due to reducing memory locality. That performance cost could result in a measureable effect on framerate. That framerate could get too low for the game to be playable for some people in your target demographic.

But none of that will happen all the time. Not every game will turn into a slideshow the moment it has a tiny malloc in the main loop.

Object pools are a performance optimization. But it is an optimization which comes with costs. They require work to implement. The code gets more convoluted. Startup time might get longer. And you either impose an artificial limitation on how many objects you want to allow or need additional logic to change the pool size at runtime, which can cause performance hickups itself.

Whenever you consider to take a performance optimization measure, ask yourself:

  • Do I actually need the performance?
  • Will it actually have a measurable benefit in my particular situation?
  • What is the cost of that performance optimization, now and for the future?
  • Is the benefit worth that cost?

So focus on creating a playable game first, then worry about the performance.

Experienced programmers are able to anticipate certain performance problems in advance and avoid them in the first place by implementing patterns which mitigate them from the beginning. But anticipating which parts of your software architecture will eat how much performance when implemented in what way requires a lot of experience. So when you are still a beginner (less than 10 years of programming experience) you should rather implement in the most straight-forward way first, measure performance and optimize afterwards.

\$\endgroup\$
2
  • \$\begingroup\$ Thanks for the thorough reply. If we're talking about the most common way to work with heap memory in modern games, would you say that object pools are used for the most part? For example, when the player shoots a gun, is the most common approach to get a new bullet entity from a big pool of pre-allocated bullet entities, or is it to allocate a new bullet entity right there and then? Again, I understand that you should always do what works best for your game and tailor the common practices to your needs, but I want to better understand how most games are developed. \$\endgroup\$
    – JensB
    Nov 21, 2021 at 11:46
  • 1
    \$\begingroup\$ @JensB Object pools are useful whenever you have a situation where entities get created and destroyed multiple times per frame. In a bullet hell shooter, you might want to use instancing for bullets. But when there are like two or three bullets on the screen at most and they survive for multiple frames, then you might not need an object pool for them. \$\endgroup\$
    – Philipp
    Nov 21, 2021 at 20:29

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .