Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Many people suggest to write a program, and then start optimizing it. But I think that when it's coming to multithreading with multicore, a little think ahead is required.
I've read about using threads, and experienced it myself during some courses at the university (still a student).

The big question is simple, but a bit abstract:

What thread related steps in game design do I need to take, before implementation?

Now trying to be more specific. Let's say, as an example, that I'm making a small board game (like Monopoly) that I want to be multithreaded.
My goal Is that this multithreaded game will exploit the best of the multicore system, lets say 4-6 cores (like in i7 processors).

My answer to this question at the moment is, one thread for each of these four basic components:

  • GUI
  • User Input / Output
  • AI (computer rival)
  • Other game related calculations (like shortest path from A to B, or level up status change)

I'm not an expert (yet!), and I'm sure there are better answers out there.
Any suggestion, answer, different approach will be helpful.

Some thoughts:
Maybe splitting the main database is a good way.. (or total disaster.. )

share|improve this question

marked as duplicate by Anko, Byte56, Trevor Powell, bummzack, Tetrad Apr 17 '13 at 23:37

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

1  
@TrevorPowell Well, I didn't see it when I asked.. But my questions is not an exact duplicate of it. –  Keeper Mar 16 '12 at 22:48

6 Answers 6

It's usually not a great idea to try and have different subsystems on different threads, because safe communication between them is often too expensive. I wouldn't want to have to use a mutex every time I recorded a mouse movement, for example. And putting AI in a separate thread creates a game design problem in real-time games; does this risk making the AI more responsive or more powerful on more powerful computers? One exception is for audio and specifically the primary buffer handling - it's common to have that in another thread because it's important that audio is being handled in a timely manner and avoids dropouts; but luckily this is usually done for you by most audio libraries.

Generally the best approach is to implement the game as a series of tasks which the different threads can execute in parallel. This scales well to as many threads as you have. You would still usually have the input-update-render loop, but the update section (and the data-processing part of the rendering) can often be split into many distinct tasks that operate on discrete pieces of data.

The most important game design concern when using such an approach is to think about how things can be updated in isolation - you can't have one of object A's update tasks altering object B or even trying to query the present state of object B, as object B may be getting altered in a different thread at the same time. So you could:

  • Ensure items that depend on each other are always processed by the same thread, perhaps by packing them into the same task;
  • Keep 2 copies of each object's state so that you can always safely read from the old one while amending the new one;
  • Send a copy of object B to object A's update task (which is basically an ad-hoc version of the previous approach);
  • Make changes via some sort of transaction and apply them via optimistic locking, repeating if it fails (which again basically copies the object and uses versioning and locking to see whether it's safe to write back into the original).

These are all pretty tricky to get right, which is why you need to think ahead as you said.

share|improve this answer

You are talking about game engine design not game design.. but getting to the topic.

Multithreading makes sense when you have logical tasks which can be divided into parts (or one logical task dividable into sub-tasks).

Normally in single threaded game you would:

  1. check user input
    • Normally os makes this "multithreded" for you as in typical situation you are just notified about clicks, touches and key presses (on mobile), and\or you polls input state like mouse position and key press state - but I don't think it is worth to put input check code into separate thread, because if your os is sending you input events, then it already is on separate thread and you just adds additional layer of complexity. Again, if you poll for input device state every frame, then your code afterwards probably depends heavily on that state, so even if you put polling in separate thread, your main thread would have to wait for the results.
  2. compute ai actions and "other game related calculations" as you named it.
    • Here you can experiment with multithreading. Think about producers and consumers pattern. For example once in a while you have a queue of units from which your code could grab objects and initiate a "computePathCommand" for each object in different thread.
  3. render game and ui
    • This should be tested but I don't think you will gain much if anything by pushing triangles to OpenGL or DirectX from separate threads simultaneously. From http://www.opengl.org/wiki/OpenGL_and_multithreading: "..it doesn't improve performance. GL function calls go to the driver and the driver collects the function calls into command lists, which finally get sent to the GPU. Usually there is just 1 GPU so there is no performance increase."

So to sum it up. Multithreading make sense mostly in the "calculations" part, think about dividable tasks in your game, prepare those tasks, create threads which will work on those tasks*, wait for threads to finish, render/draw the results, repeat :).

  • Aditional tip - creating more threads than cpu cores, will not bring you performance increase.
share|improve this answer
2  
Aditional tip - creating more threads than cpu cores, will not bring you performance increase. That's not necessarily true. Having critical threads block on IO can be a big problem. –  stephelton Mar 16 '12 at 16:47
    
Having more threads busy than cpu cores will not bring performance. In fact, it can (and will) hurt performance. –  stephelton Mar 16 '12 at 16:56
    
And that's what I have written, or..? –  Kamil Mar 19 '12 at 10:58

One thing I haven't seen in any answers yet is a split-and-join tactic. This works particularly well when there are numerous cores available (like the PS3's SPUs), or where excessive IO blocking would cause the CPU to be underutilized.

If you have a lot of work that can be calculated independently, you can spawn several threads (or a thread pool) to do the work, give each thread some work, then wait for them all to finish (join) and then move on. This has the advantage of being a fairly localized design change (most of the other things talked about so far have very far-reaching design considerations). However, it can be difficult to find a situation where something like this would actually work and pay off.

share|improve this answer
    
That is pretty much the task-based approach that I was referring to, but perhaps I didn't make it clear enough. –  Kylotan Mar 16 '12 at 21:34

What you have isn't a bad way to start, but I'd make the UI thread the main game thread as well. Work out a strong messaging system with commands and command queues for the different threads to communicate so that you minimize the number of synchronization points.

Other places that could be threaded depending on your implementation:

  • Sound
  • Physics/Animation
  • Resource Loading
  • Networking

Basically think of different subsystems and think, "Would it be bad if this system was one to two frames out of sync with this other system." If it isn't then they could be off-loaded.

And for some of the answers above, Multi-threaded rendering doesn't mean rendering from multiple threads usually, but rather moving the rendering from the main game thread so that you are not locking the FPS of the renderer to the FPS of other parts of the system.

share|improve this answer

Interesting question!

Here's my input:

Maybe monopoly isn't the best example for intensive needs for computation, but i get your point. Also, it's a good idea to plan the architecture as thoroughly as possible, and sooner, rather than later!

I'd say that the best use for multicores should be paralelization of AI calculations, as they are the most resource-hungry aspects i can think of, other than graphics (except if you somehow decide to have an extremely detailed 3d monopoly board). But from here, any solution is deeply linked to the game you're coding.

What do you mean by "splitting the main database"?

share|improve this answer
    
It was just a thought.. When you have a main source from which all threads read, it can make multithreading useless.. Something like splitting the data to more used, and less used.. I didn't give it much thought... –  Keeper Mar 16 '12 at 14:58
    
hum, that may depend on the ammount of data you're handling (AI calcs can generate a lot of data) - but for storing a board, pieces and things like that, it's probably not worth it. –  JoséNunoFerreira Mar 16 '12 at 15:09

I invoke the Wisdom of the Ancients:

Yoda says

Bad premature optimisation is. Exceptions this does not have.

Brian Kernighan says

Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.

Threading is optimisation. It's very clever optimisation.

Do it only once it becomes necessary or you will wind up writing, debugging and pondering all things inconsequential. Certainly don't start with it!

share|improve this answer
1  
Mysterious are the ways of the force... –  Keeper Mar 16 '12 at 18:09
    
"Yes, a Jedi's strength flows from the Force. But beware of the dark side." –  Anko Mar 16 '12 at 18:17
    
In general, I agree with what you're saying regarding optimisation, but I think this situation is different. For example, if your entity update requires access to the world in order to iterate over other entities, then your ability to spread that across multiple threads is already severely limited. –  Kylotan Mar 16 '12 at 21:37
    
The true master knows that exceptions this does have. Don't forget that what Knuth actually said was: "97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%. A good programmer will not be lulled into complacency by such reasoning; he will be wise to look carefully at the critical code; but only after that code has been identified". I see this misquoted (or partially quoted) as reasoning against any kind of optimization so often, and it's borderline annoying... –  Jimmy Shelter Mar 17 '12 at 0:08
4  
I don't really agree with the message in this answer. Threading issues are best considered before the interactions of large systems are implemented. At the same time, they are very pivotal points of design in the system and are huge points of optimization. A good high-level design will include consideration of multithreaded implementation. Premature optimization can certainly be a bad thing, but when designing large systems and their interactions, multithreading considerations are not necessarily "premature." After all, we're talking about some of the biggest decisions that will be involved. –  stephelton Mar 17 '12 at 3:12

Not the answer you're looking for? Browse other questions tagged or ask your own question.