What should threads be used for realistically?

Started by
6 comments, last by the_edd 14 years, 7 months ago
I am curious what you should use threads for in game programming. I can think of everything working in 2 ways: 1) use lots of threads and callbacks to run your game, or 2) have your game stick solely to a loop and only execute things in order. Obviously I couldn't avoid threads entirely, especially since some launch without me even realizing it (network stuff, for example), but is there anything else I should try to use them or avoid using them with? Thanks.
Advertisement
jonathanplumb
Hi. A very high-level description:
You'd need threads to do anything that requires you to modify data from varying places without corrupting the data itself. Imagine reading from a socket in one thread and the graphic renderer in another thread. Those are for games.
In other applications of threads, imagine you are playing a song in a multimedia player. There could be 2 threads here. One doing the actual playback decoding, the second displaying the progress_bar/song_ticker etc..

In general, threads are not only used in gaming but pretty much everywhere these days.

Quote:
2) have your game stick solely to a loop and only execute things in order.

This would be tricky because your code can not execute everything sequentially and expect a sane result especially if it involves user interaction. The result if you used sequential way would be I imagine the whole application would appear to hang(block) to the user while its doing its sequential processing. So, it'd make sense to wrap the actual GL/DirectX stuffs in one thread and do input handling and network stuffs in other different thread(s).

The stuffs I have replied is very general. Please proceed with more in-depth reading by Googling around (Wikipedia is a good starting point).
1) Avoid using them untill you've got something that works without them. It is good to understand how the serial versions of things work before trying to improve on that. Threading has a LOT of pitfalls. When it is time to try out threading, pick something trivially parallel to work on, like a ray tracer.

2) Things to thread?
A) "for loops". Any time you have "for X do Y" see if the work is non trivial (ie updating 100 AI units, or 10,000 particles), and if the data can be buffered (this frame and next frame buffers) OR better yet just split up with no interdependency. Then split the update function across N == # of cores threads (100/N units per thread 10,000/N particles per thread) to update everything much faster.

B) Subsystems that need to be asynchronous in how they use processor time. This would be your network processing, graphics rendering, user input, etc. By putting that in a thread you end up with a system that can render at 5fps but still take input at 30fps, making it fell slightly more smooth.


2A is likely harder to implement without your code changing drastically, but it scales with the number of cores.
2B seems simple by comparison, since cordoning things off with a few critical sections seems easy enough. But it doesn't scale beyond X cores, where X is the number of subsystems you can figure out how to detach from oneanother. AND it can be hard to cut the interdependence of subsystems in a meaningful way, meaning you still have a mostly serial system.
Thanks both of you for your input. So I'm figuring I should finish my "learning" phase with minimal threads, and when it's time to actually attempt a real project with a team, maybe look more into what should or shouldn't be threaded.

Also, should timers always be threaded? (IE: A timer that executes a block of code when it finishes the given time)
well, when you finish executing a timer function, you can use a function pointer as a callback to specifically tell it to execute the it after the timer has reach 10s (e.g., if say starting from 0s....10s).

Other way could be having a thread checking for timer's time every 1 second and if and when it hits 10s, execute the function required(again this could be a functor) and return. You don't strictly require thread to do this however need you thread if you were trying to display the value to use in user-interface the same time that your timer checking code is executing(achieving code parallelism by using multiple threads within 1 executable process).

Again, very high-level but hope it helps. :-)
Definitely above my level ... but that's how we get better right?

Thanks a lot for the pointers.
Quote:Original post by jonathanplumb
I am curious what you should use threads for in game programming. I can think of everything working in 2 ways: 1) use lots of threads and callbacks to run your game, or 2) have your game stick solely to a loop and only execute things in order.

Obviously I couldn't avoid threads entirely, especially since some launch without me even realizing it (network stuff, for example), but is there anything else I should try to use them or avoid using them with?

Thanks.


For most games you can avoid threads entierly, in fact most games written before year 2000 was singlethreaded.

Once you got a bit more experience you can look into multithreading and how it applies to games. (Mostly its only used to either deal with functions that block while waiting for external resources (You can look into asynchronous i/o for most of these cases instead) or to take advantage of multiple cpu cores.
[size="1"]I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!
Quote:Original post by KulSeran
1) Avoid using them untill you've got something that works without them. It is good to understand how the serial versions of things work before trying to improve on that. Threading has a LOT of pitfalls. When it is time to try out threading, pick something trivially parallel to work on, like a ray tracer.


Perhaps you weren't saying this exactly, but in most situations it is incredibly difficult to retrofit serial code so that it executes in parallel. Threading and concurrency in general often affect interfaces as well as implementation, sadly.

So my advice would be to create things like a single-threaded task queue that may be swapped-in in place of the multithreaded queue. You can switch to the serial queue for debugging if you start suspecting race conditions and such-like.

This topic is closed to new replies.

Advertisement