🔒 Locked
Multithreaded Game
Advertisement
Original Post
I had an idea. What if you were to put tasks such as rendering and input in their own threads? That way, you could recieve input where the main loop happens to be. Remember how sometimes when you''re playing a game, you press a key, but the game totally misses it? Wouldn''t multithreading solve that problem? WHICH then leads me to some questions:
1) When the main thread recieves a message, does it automatically send it to all the other threads of the proccess, and vice versa?
2) Even if i were to have a seperatie thread for input and rendering, wouldn''t it be useless anyway (just got these thoughts)? I mean, you''d have to mutex the input thread so it doesn''t switch to the rendering thread before input is complete (since what is rendered is determined by input), and youd have to mutex the rendering thread so that drawing is done before it switches to the input thread! So what are the advantages? Or should only input have a seperate thread? Or rendering?
As you can see, I have many little questions regarding how it would work together overall, and how i would set this up to get it to work with the advantages i stated earlier.
Definately for sound, but I think it would be kind of difficult to pull off proper input and graphics if they are running on seperate threads like that.
You could probably stick some graphics stuff in another thread, but only if it is stuff that doesn''t rely on user movement.
many games essentially have all actors running on a seperate "thread", although their implementations are quite a bit different than say a windows thready.
You could probably stick some graphics stuff in another thread, but only if it is stuff that doesn''t rely on user movement.
many games essentially have all actors running on a seperate "thread", although their implementations are quite a bit different than say a windows thready.
Most commercially released games do not use multithreading. Age Of Empires 2 for example. It''s single-threaded. Quake 3 only added multi-threading to cater for SMP (symmetric multi-processing) systems.
The only place I have seen multi-threading warranted is when implementing multiplayer. Reading the network packets is time-critical, so having a simple thread just doing this task is a good thing.
Steve 'Sly' Williams
Tools Developer
Krome Studios
The only place I have seen multi-threading warranted is when implementing multiplayer. Reading the network packets is time-critical, so having a simple thread just doing this task is a good thing.
Steve 'Sly' Williams
Tools Developer
Krome Studios
If you read the UnrealEd docs, it basically explains how each actor runs on its own "thread".
Now this isn''t truly a "thread" as in a windows thread, but rather the classes are very well seperated so as to effectively be independent of one another.
Playing with the UnrealEd Scripts, I have to say I really like the way they laid the whole thing out. (Not like I am one to be a critic though
)
Now this isn''t truly a "thread" as in a windows thread, but rather the classes are very well seperated so as to effectively be independent of one another.
Playing with the UnrealEd Scripts, I have to say I really like the way they laid the whole thing out. (Not like I am one to be a critic though
High perforamce graphics packages use multiple threads so that mulitple processors can be utilized.
My game currently uses 4 threads, one for window messages and OnIdle rendering, another for a client socket, a third for a server socket, and a fourth for input.
The graphics thread only reads the position data, and the input thread reads & writes, so it could work without any sycronization at all and be thread safe (though not multi-processor safe). At worst, a frame would disjointly display a single object... lock & unlock your geometry if its a big concern...
Winodws blows a lot of processing power during thread-thrashing. But at any given time there are twenty or more processes running plus some more threads for each of them... so if you have 6 thread dedicated to your game, you get a bigger slice of the pie than if you only had one
(well not really, but it sounds good
)
And no, when a thread receives a message it definetly does not send it to any other thread - unless you specifically code it too! How would it know when to stop? Thread1->msg->Thread2->msg->Thread1.... 100% cpu utilization & grid lock (not quite dead lock though)
Threads share memory, so they can "communicate" via global memory and/or messages. So for the input, you would create an input thread, initialize dInput, make a threadproc that just polls the keyboard once every 10ms and stores it in a buffer until the render loop ask for it (then it clears the buffer). Thread should be bumped up to real time priority so that it always gets called every 10ms (well as close to every 10ms as windows will let it anyway...)
You just need to use some thread safe code in the input routine.
Don''t screw-up a real time thread, and make it spin in a tight loop! If you do, you''ll be a hittin'' the reset button
My game currently uses 4 threads, one for window messages and OnIdle rendering, another for a client socket, a third for a server socket, and a fourth for input.
The graphics thread only reads the position data, and the input thread reads & writes, so it could work without any sycronization at all and be thread safe (though not multi-processor safe). At worst, a frame would disjointly display a single object... lock & unlock your geometry if its a big concern...
Winodws blows a lot of processing power during thread-thrashing. But at any given time there are twenty or more processes running plus some more threads for each of them... so if you have 6 thread dedicated to your game, you get a bigger slice of the pie than if you only had one
And no, when a thread receives a message it definetly does not send it to any other thread - unless you specifically code it too! How would it know when to stop? Thread1->msg->Thread2->msg->Thread1.... 100% cpu utilization & grid lock (not quite dead lock though)
Threads share memory, so they can "communicate" via global memory and/or messages. So for the input, you would create an input thread, initialize dInput, make a threadproc that just polls the keyboard once every 10ms and stores it in a buffer until the render loop ask for it (then it clears the buffer). Thread should be bumped up to real time priority so that it always gets called every 10ms (well as close to every 10ms as windows will let it anyway...)
You just need to use some thread safe code in the input routine.
Don''t screw-up a real time thread, and make it spin in a tight loop! If you do, you''ll be a hittin'' the reset button
|
Yeah, I''ve done this with before and have continued to do this is many projects I''ve done before...
What I do is keep the render code in one thread and all other game stuff in another thread, and it works quite well because the render thread only reads the values.
I''ve been wondering if anyone else has done this too...
Korndog
"Look for the new ANB engine!"
What I do is keep the render code in one thread and all other game stuff in another thread, and it works quite well because the render thread only reads the values.
I''ve been wondering if anyone else has done this too...
Korndog
"Look for the new ANB engine!"
I use a seperate thread to:
render 2d special effects- (since they are actually a low priority, think about it-)
handle http requests sync. (using wininet)
handle basic logic- move sprites, play sounds etc.
I don''t see any speed loss from multithreading- and it makes the code simpler. I did have a problem within Win2k though- it seems real sensitive to the thread priority level when 98 is not...
One trick to send info/flags between threads is to use 32-bit dwords- since a single processor system cannot create an exception because only a single ASM command in needed to change there state. (Hope this isn''t too confusing...)
ill-lusion.com
ziggy@ill-lusion.com
render 2d special effects- (since they are actually a low priority, think about it-)
handle http requests sync. (using wininet)
handle basic logic- move sprites, play sounds etc.
I don''t see any speed loss from multithreading- and it makes the code simpler. I did have a problem within Win2k though- it seems real sensitive to the thread priority level when 98 is not...
One trick to send info/flags between threads is to use 32-bit dwords- since a single processor system cannot create an exception because only a single ASM command in needed to change there state. (Hope this isn''t too confusing...)
ill-lusion.com
ziggy@ill-lusion.com
One job for multithreading is mouse-handling.
If you want a good interface-response in your game you should separate mouse from main rendering loop. If fps drops you can still interact with the gameinterface in a fast way.
You can notice this if you have ever played games which dont support this, the mouse-movement is so slugish.
One of the most important part of game is the interface-response and if its slow then imo the game will suck , even it has nice gfx etc.
You still have to sync your mouse-drawing routines with the main rendering loop but its it worth.
If you want a good interface-response in your game you should separate mouse from main rendering loop. If fps drops you can still interact with the gameinterface in a fast way.
You can notice this if you have ever played games which dont support this, the mouse-movement is so slugish.
One of the most important part of game is the interface-response and if its slow then imo the game will suck , even it has nice gfx etc.
You still have to sync your mouse-drawing routines with the main rendering loop but its it worth.
That''s the tricky part of multi-threaded processes.
The best method would be to use events to signal other processes to wake up. For example, you''d receive a message with one thread, enter a CRITICAL SECTION, set a flag that alarms the main thread of the message and copies all necessary data... (NOTE the copy, its never a good idea to use the same memory over 2 different processes. Often leads to horrible memory bugs... they can happen and your program might continue for another 5 minutes before crashing... Unless you enter a critical section every time.)
The critical sections are nice, but don''t go crazy, because they lead to another problem.... deadlock... where one thread is waiting on a critical section that it can never get. This is a huge topic... and hard to cover here.
So my advice... start a worker thread, it will wait on an event to be activated. When that happens, use a semaphore (or lock) to protect a local data member, enter the critical section, modify that data... Leave the critical section by releasing the semaphore or lock... and loop back around to wait on the event...
You can create these variables as object members (so they aren''t global, and pass them as parameters) When you initialize your game.
Hope that makes sense, its a difficult topic and hard to explain in a short email.
Lawrence Ohab
The best method would be to use events to signal other processes to wake up. For example, you''d receive a message with one thread, enter a CRITICAL SECTION, set a flag that alarms the main thread of the message and copies all necessary data... (NOTE the copy, its never a good idea to use the same memory over 2 different processes. Often leads to horrible memory bugs... they can happen and your program might continue for another 5 minutes before crashing... Unless you enter a critical section every time.)
The critical sections are nice, but don''t go crazy, because they lead to another problem.... deadlock... where one thread is waiting on a critical section that it can never get. This is a huge topic... and hard to cover here.
So my advice... start a worker thread, it will wait on an event to be activated. When that happens, use a semaphore (or lock) to protect a local data member, enter the critical section, modify that data... Leave the critical section by releasing the semaphore or lock... and loop back around to wait on the event...
You can create these variables as object members (so they aren''t global, and pass them as parameters) When you initialize your game.
Hope that makes sense, its a difficult topic and hard to explain in a short email.
Lawrence Ohab
In the Win32 environment, you lose nothing by using threads (unless you use them very poorly).
It''s already swapping between 30-40 threads, what''s another 3-8?
...
And the mouse comes back on an interaupt, it should be possible to update the cursor position damn quick. Or do you have to poll it like the keyboard?
Sometime you *must* use threads. For instance, if you were recording a live audio stream; you need work thread dedicated to the events; otherwise when the user moves the window around or clicks a menu and fuddles around - you''ll get a buffer underrun.
It''s already swapping between 30-40 threads, what''s another 3-8?
...
And the mouse comes back on an interaupt, it should be possible to update the cursor position damn quick. Or do you have to poll it like the keyboard?
Sometime you *must* use threads. For instance, if you were recording a live audio stream; you need work thread dedicated to the events; otherwise when the user moves the window around or clicks a menu and fuddles around - you''ll get a buffer underrun.
Threading is good.
In my experience using multithreading, the overhead of using them on single CPU systems (in terms of increased memory usage and thread switching time) is negligible.
And the gains when the program is run on a multiple CPU system (with an OS that can really support it, like Win2k or Linux) can be quite high, if you multithread wisely.
In my experience using multithreading, the overhead of using them on single CPU systems (in terms of increased memory usage and thread switching time) is negligible.
And the gains when the program is run on a multiple CPU system (with an OS that can really support it, like Win2k or Linux) can be quite high, if you multithread wisely.
Well, on single processor systems, multithreading doesn't really do anything special. In such an environment, processing updates to your game objects in an incremental manner would really be the same as an OS "updating" threads with time-slices.
In dual (or more) processor systems, things get interesting, but you really have new issues to deal with, like syncronization/data access/blahblah. It is NOT easy to design parallel/superscalar applications... but that I suppose that complexity scales linearly program complexity.
Having an isolating a rendering thread might be an interesting way to stabilize rendering FPS when other game code is running slow though...
Edited by - revolver on October 28, 2000 5:00:38 AM
In dual (or more) processor systems, things get interesting, but you really have new issues to deal with, like syncronization/data access/blahblah. It is NOT easy to design parallel/superscalar applications... but that I suppose that complexity scales linearly program complexity.
Having an isolating a rendering thread might be an interesting way to stabilize rendering FPS when other game code is running slow though...
Edited by - revolver on October 28, 2000 5:00:38 AM
Another use for threads is for streaming in new areas as you approach them (similiar to streaming music data).
And yeah I usually use Dinput with the mouse on a seperate thread.
(not the keyboard though, I handle that usually via a 256 byte array for storing what keys are currently up and what are currently down).
And yeah I usually use Dinput with the mouse on a seperate thread.
(not the keyboard though, I handle that usually via a 256 byte array for storing what keys are currently up and what are currently down).
I designed a WinThread class in C++ (for Win9x/NT) that works just like the Thread class in Java. I''d appreciate it if you guys could download the source code, test it, and try to break it.
I included a sample test program you can use to see how it works if you are unfamiliar with Java threads.
www.eecs.ukans.edu\~millew
millew@eecs.ukans.edu
I included a sample test program you can use to see how it works if you are unfamiliar with Java threads.
www.eecs.ukans.edu\~millew
millew@eecs.ukans.edu
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement