Jump to content

I don't know if I should ask this


Auntie Mangos

Recommended Posts

  • 40 years later...

Its good to hear that. Now lets make this Thread to be exactly for this forum by asking the question.

I need an advice about game design, especially the main loop. All the books I found are about single threaded game desing. Lets start with the good old known main loop

while (MessageMgr.PeekMessage())
{
               game.UpdateEnvironment();
               game.RenderEnvironment();
}

Would it be better if the rendering part and input/update part are separated in two threads? Is this doable?

- one thread for the rendering

- and another for input(keyboard/Mouse) and game environment

And on game start

   threadUpdateEnvironment.Start();
   threadRenderEnvironment.Start()

and at the end

threadUpdateEnvironment.Abort();
threadRenderEnvironment.Abort();

Further more could the enviroment thread be with higher priority than the render thread.

For example

in this case if game is running slow, graphics may skip some "things" but actual game would be running without delays. (since my graphic part realy is baad at this moment)

Third thing is what if I make a thread for every unit to handle its AI calculation

so that every unit have its own thread for UpdateAI() like functions.

In this way AI part

foreach(unit unt in i_units) 
un.UpdateAI(msecs)

will be excluded from the usual UpdateEnvironment() method

Is this even a right approach to do this?

I ask this because in this forum there are people that know way much more that me, about performance and threading.

Link to comment
Share on other sites

As long as only the updating thread writes data, it should work fine. However, you will probably need to use locks appropriately to make sure the renderer only renders complete sets of data and not halfway through an update.

Using threads for every unit is a bad idea. Threads are expensive. One or a few AI threads is a good idea, but many AI threads will actually kill any performance increase.

Link to comment
Share on other sites

To explain a bit more - a multitasking / multithread OS can handle several processes / threads, but the CPU itself cannot. The OS has to not only divide the time between threads/processes, but it also needs to backup&restore register sets for those threads. Ie. if thread 1 is currently active and it's time to run thread 2, the OS (well, kernel) needs to save registers of thread 1 somewhere, restore second thread's registers (from already saved state) and continue execution of thread 2. Some CPUs (I believe it's called HyperThreading) can store (mostly) 2 registers sets, so - for two simultaneous threads - you don't need to do this save&restore things. But since no major kernel / OS uses 2-8 threads only, there still has to be done some of the work. So in general - if you have, say, 2000 threads, you need about 2000 CPU cores to run those threads efficiently.

Context switches do really cost some CPU time, therefore 20 threads is still okay, but 200 is not.

To original question - go for a separate thread with input handling. Many events can be taken care of without interfering with other threads - like when a user presses an Alt key, you don't need to store that state in some "main thread", you can simply poll for the next key input. Things like menus could have it's own thread as well (or perhaps be in the input thread), so if the rendering core locks up for some reason, the user can still interact with the application.

And - of course - you need to take care of mutex locks, spinlocks, semaphores, atomic operations and all the stuff that comes with multithreading.

Link to comment
Share on other sites

The priority is decided by the CPU scheduler in the kernel. Pretty much all today's CPU schedulers do some sort of fair task/thread switching, so there's a VERY low chance your input thread gets completely stuck because some other thread/process is "using the CPU on 100%".

Link to comment
Share on other sites

First of all I want to thank all of you guys taking part in this thread. Your advices are very helpfull to me. I appreciate it.

Here is what I will do first

1. I am forgetting about every unit in it's own thread.

2. Move input to a separate thread

I think I can do it in a separate thread since, for key/mouse handling, I use array of booleans and I check if specific key is true in this array.

3. I didn't thought about that gamedata is a critical section, this wil be next to take in consideration.

Here is some pseudo/C#/C++ code for the three threads

// 1st thread: Handles kbd & mouse
Thread threadInput = new Thread();
threadInput.Priority = ThreadPriority.Normal;

// 2nd thread: Handles Updating gameData
Thread threadUpdateEnvironment = new Thread();
threadUpdateEnvironment.Priority = ThreadPriority.Normal;

// get elapsed time
// if (game.isPaused()) continue;
// buildings updateAI(elapsedTime);
// loop units updateAI(elapsedTime);

// 3rd thread: render world
Thread threadRender = new Thread();
threadRender.Priority = ThreadPriority.BellowNormal;

// condition for fps limitation to 50 fps
// render for GraphicDevice

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. Privacy Policy Terms of Use