Is multithreading nessecary for real time 3d games, because I´ve always done it in the way to call update and paint in a loop without threading.
So my question: Do I need to/should use multithreading or is it better without it?
Thanks in advance!
So my question: Do I need to/should use multithreading or is it better without it?
I'd say "for simpler games" there's no need for multithreading at all. Unless perhaps on Atoms, but even those are going to run "simpler games" at interactive rates, albeit with some sweat.
As I noted above, fundamentally, for simpler games, if you have any respectable amount of disk access, you, at the very minimum, should have a disk access thread that processes all disk-read jobs and queues completed read jobs for another thread for parallel processing while it processes the next disk read task.
Seconded. Given today's processors, I hardly believe a beginner can saturate them. Of course one can always do things wrong in the first place.
Have you run into a performance wall with single-core, where you simply can't make your game run at interactive frame-rates?
If so, then you need to multi-thread your game.
Generally speaking, the number of threads you have should be equal to the number of processors that are available[/quote][/font]
Generally speaking, your threads should not be likely to block on things. You should use non-blocking file-system and networking APIs, which removes the need for them to have their own threads (at a low level, these things are implemented asynchronously, using efficient methods such as DMA etc. The blocking APIs are a wrapper around things that are natively asynchronous, so if you then wrap up the blocking APIs with threads to make them asynchronous again, you've succeeded in adding two redundant layers of inefficiency to an operation that cancel each other out for zero benefit).
Actually you may want more threads than cores. Consider a single-core cpu. It can still benefit from having multiple threads, especially if each thread is likely to block on something. If you have a single core, and 4 threads:
- game logic & render thread : constantly runs, 'interrupted' by occasional work in the other threads
- sound thread : will periodically do a 'spurt' of work processing audio every so often. most of the time it's waiting
- network thread : will spend most of its time blocked, waiting on a socket
- file thread: will spend most of its time either waiting for the game to ask to load something, or blocked on a slow disk operation
On a modern OS, when a thread is blocked on something, such as waiting for the disk to read something, the kernel will set that thread aside, and run something in the another thread.[/quote]On windows, it also (by default) wont wake that blocked thread up for at least 15ms, even if it only needs to block for 0.5ms, which isn't very good for a real-time system, hence you should avoid blocking.At the very minimum, multithreading is essential for fast resource loading...you have any respectable amount of disk access, you, at the very minimum, should have a disk access thread that processes all disk-read jobs and queues completed read jobs for another threadAs above, just use the OS's native asynchronous file APIs. You only need a background loading thread if you've got long-running post-load CPU work to do, such as LZMA decompression or XML parsing.
On windows, it also (by default) wont wake that blocked thread up for at least 15ms, even if it only needs to block for 0.5ms, which isn't very good for a real-time system, hence you should avoid blocking.
This is really more for my sake than anything, but I was under the impression that this tidbit only held for explicit calls to Sleep(), and things like WaitForSingleObject() and friends can potentially be more responsive?It doesn't matter how you transition a thread into a sleep state - once in that state, the kernel's scheduler won't come around and poke it back into a ready state until the next scheduling cycle, which defaultsto15ms on windows IIRC.
It doesn't matter how you transition a thread into a sleep state - once in that state, the kernel's scheduler won't come around and poke it back into a ready state until the next scheduling cycle, which defaultsto15ms on windows IIRC.
timeBeginPeriod(1);
Sleep(1);
timeEndPeriod(1);
[quote name='Hodgman' timestamp='1328684518' post='4910803']
It doesn't matter how you transition a thread into a sleep state - once in that state, the kernel's scheduler won't come around and poke it back into a ready state until the next scheduling cycle, which defaultsto15ms on windows IIRC.
timeBeginPeriod(1);
Sleep(1);
timeEndPeriod(1);
(from msdn.microsoft.com)
Use caution when calling timeBeginPeriod, as frequent calls can significantly affect the system clock, system power usage, and the scheduler. If you call timeBeginPeriod, call it one time early in the application and be sure to call the timeEndPeriod function at the very end of the application.[/quote]
timeBeginPeriod(1);
Sleep(1);
timeEndPeriod(1);
Is this a bad idea (too much overhead, slowing down the OS) ?In my experience, it seems to be fairly common practice to call [font=courier new,courier,monospace]timeBeginPeriod[/font]/[font=courier new,courier,monospace]timeEndPeriod[/font] in your main function (i.e. applying the increased scheduling precision for the entire life of your program). N.B. you're also supposed to use [font=courier new,courier,monospace]timeGetDevCaps[/font] to find the system's minimum value, instead of using a hard-coded [font=courier new,courier,monospace]1[/font].var drawState = new DrawState[2];lock { updateIndex = 0; drawIndex = 1; }
or
lock { updateIndex = 1; drawIndex = 0; }Draw() { drawState = state[drawIndex]; }
Update() { drawState = state[updateIndex]; }
But when it comes to processing more complex structures, like the entities in an Octree, I keep finding blocks where the code will end up becoming serialised regardless of threading
I don't see a problem with traversing a tree in parallel. Updating it with new state is the issue of course. With "lock step" threading I can see how it would work. Jobs run, store their results, all results are applied to the tree at the end. I'd be sceptical about the resulting performance improvements of course. Anyway will check out the BF presentation later.
This topic has been locked by a moderator. New replies are not allowed.
With your permission, GameDev.net uses analytics cookies to understand how people use the platform. You can accept analytics or continue with necessary cookies only. Learn more