Multi-threaded game

Started by
11 comments, last by I_Smell_Tuna 18 years, 5 months ago
Quote:Original post by I_Smell_Tuna
Ok, I'm making a 3D video game and I want to put my various sub-systems on their own threads - for obvious performance reasons - while grouping dependant sub-systems together on a thread. I plan on doing this by double buffering the game data. To do this each sub-system will have a version of the game data that it updates before each loop iteration. When a sub-system loop finishes it will update the back buffer and swap the buffers.

Does anybody see a problem with this method for multi-threading a video game? The only thing I can think of is that it will consume more memory.




How do you define "sub-systems" (what are the ones you plan to use...)?

AI stuff like pathfinding is batchable and somewhat independant (yet requiring access to the current world data).

File operations (like loading assets on the fly) can be seperated.

Communications (if you have significant packet traffic)

Sound/Music management

if your animation/physics are a heavy load, you might want the rest of the game engine running on the other CPU.

Why keep seperate copies of the game data when each processor can access the same data in memory (and then maintain their own local working data).
You may still have to maintain a READ & MODIFY/UPDATE phases/cycle to eliminate
threads trying to read partially changed shared data.

Advertisement
For most intents and purposes, on PC, multi-core is equal to multi-CPU. Hyper-threaded, however, is nowhere near multi-core (or multi-CPU).

There are two possible performance problems with threaded systems:

1) Synchronization has a penalty, and may additionally incur jitter caused by the OS scheduler.

2) Multiple threads (and even multiple cores) means multiple things competing for your memory bus. Your memory bus is already often the bottleneck in the system. More doesn't mean better at this point -- in fact, copying your state around a lot just means you add more memory traffic.

For I/O-like things, like asynchronous file and network read/write, and sound mixing, a separate thread for the subsystem (or thread pool, even) will make sense. For highly de-coupled compute-bound systems, a thread per system MAY make sense, if you can buffer the data sufficiently without paying additional copying overhead.

I would look at the NovodeX SDK (free download) for how to structure physical simulation as a sub-thread (although in their case, that thread may even be actual hardware). You could also conceive of a separate thread for rendering a set of game state to the screen -- although modern GPUs already do a good job of parallelizing this, using their own CPU.

So, the most I can see threading a current gaming engine would be:

- I/O in its own thread pool (for asynchronicity, not computation)
- Sound mixing in its own thread (for real-time scheduling, not really compute bound on modern CPUs)
- Physics simulation in its own thread (or on hardware)
- Rendering in its own thread
- "the main thread" which coordinates the others, reads user input, reaps physics output and sends back instructions for next frame, and funnels game state to the renderer for presentation

I would probably put AI in the main thread, or a fiber of the main thread, because I don't think the gains are there in trying to put that in a separate thread. Also, AI will be compute bound without any clear synchronization points, which means that it might hog the CPU for an entire scheduling quanta on a non-multicore system, which would lead to stuttering frame rates.
enum Bool { True, False, FileNotFound };
Separating your rendering engine from the rest of your game is easy. All it needs to do is read the scene data, so just copy the data to your thread from the global data, and let the rest of the program continue. This should give you a pretty high FPS on a dual-core/multi-proc system.

This topic is closed to new replies.

Advertisement