Game and GC

Chris Katko ckatko at gmail.com
Fri Apr 6 21:55:09 UTC 2018


I'm in the same boat. I do games. But I love D's syntax and 
template power. So I'm doing a full experiment.

Honestly, if D is that big a liability, you'll encounter it long 
before it's "too late" to port it to C++.

Last night I had stuttering issues, but I realized there was a 
single, C-function, being called too many times (and never 
deallocating!).

But previously, I've also had stutter issues. Now granted, I test 
on a "crap" laptop 2 GB RAM / Celeron processor. But it'll be 60 
FPS ... then spike down. If this happens again with my current 
project, what I'm going to do, is hack the open source garbage 
collector to fire off an event/console message EVERY TIME it 
actually pauses to collect. Because it's possible the GC isn't 
actually the problem, or, some simple change to a line of code 
may prevent the GC from being a problem.

That said, there's also @nogc (but that's also a bit of a lie 
because they never tell you that ANY THREAD running GC code can 
pause ALL THREADS for a collection.)

But if you're making games, you should really be using static 
pools anyway. What's the MAXIMUM number of objects/trees/maps 
your game will have at a time? It's simple (regardless of D, C, 
Python, or Lua). Static. Pools. Basically, you just allocate at 
startup a simple fixed-length array for all your objects. That 
way, you're never asking the OS for memory = Never needing the 
garbage collector. If you don't use all that memory? Who cares. 
RAM is cheap. And if your program CAN swell in size, that means 
your low-end PCs will fail without knowing why.

So you just put all your objects in fixed length arrays of size 
MAX_OBJECTS, MAX_ENEMIES, MAX_ITEMS, etc. And deleting an object 
is as simple as erasing it, or marking it as "bool is_deleted = 
true;" and adding a new object is simply finding the first 
"is_deleted" and re-running the constructor / re-using the 
carcass of the dead object.

99% of AAA studios use static pools. Now technically, static 
pools are "chunks" of fixed length arrays. So you could have one 
pool for a "map", and start loading another pool for the next map 
you're going to enter, and then when you finally transfer to the 
next map, you then free the static pool by marking it as deleted. 
And repeat as necessary. So it's a very macro-level amount of 
allocations. We're talking like, less than a dozen actual 
entities. (Depends on gametype, of course. But the 
order-of-magnitude helps convey it.)


More information about the Digitalmars-d-learn mailing list