Hello. I’m about to start making a 3D RTS game after having tested out many of the parts that I will need for it (fog of war, occlusion testing, etc etc). I’ve realized that many of the CPU-bound tasks are highly threadable. I have seen the performance benefits of going from 1 to 2 threads, for example splitting updating (CPU-heavy 2D physics) and rendering. Therefore I would like to make this game scalable to any number of processors to some extent.
The problem is that I have tasks with different priorities. Examples:
- In a small test program I did frustum culling in a different thread in parallel to the game updating. There is no need to pause the game loop while the test is running, as one frame old culling results are perfectly fine. This gave a huge performance boost when CPU-bound, sometimes +100%. Code example:
level.processCullingResults(); //Wait for culling thread(s) to finish, if they are not done yet. Then apply the result to the level.
level.startFrustumCulling(); //Start the thread(s) again.
level.renderLevel(); //Render the level
Display.update(); //LWJGL buffer swap
-
Pathfinding is most likely extremely threadable. Considering the fact that multiple units will most likely receive move orders at the same time (a simple group move), pathfinding can be threaded per unit as long as the paths don’t affect each other (more advanced algorithms). Due to the tight client-server synchronization required, pathfinding will have to pause the game loop. This is a very nice thing to thread, as if a player orders 100+ units to move a long distancee to attack the enemy base, it could give a warning to the defending player as the game could freeze for a second or two due to pathfinding calculation. I’ve had that happen VS 7 CPU players in Warhammer 40k. xD
-
Some of my fog of war code is also threadable in some heavy preprocessing steps that have to be redone when the map changes (which happens quite a lot).
All of these steps could in theory use any number of threads to do their calculations. My current idea is to have this thread layout:
- One high priority master/rendering thread. Helps as LWJGL only allows OpenGL calls from one thread. This thread controls all other worker threads.
- X high priority worker threads, where X is the number of processors available. These threads will do calculations that are threadable but requires the master thread to be paused (pathfinding, fog of war, and more), and will therefore never compete with the master thread for resources.
- 1 or more low priority frustum culling threads. These threads are set to low priority to reduce their effect on the master thread and the worker threads which are more time sensitive. They will however be given time to complete if necessary.
- (Network threads and sound threads are easily implemented and won’t affect performance noticeably.)
Am I doing things right? I haven’t found many tutorials/documents on threading games in specific… I may be overdoing things with this intense multithreading, and I probably will cut corners for simplicity, but I believe this will make the game more smooth and professional looking. I’m not entirely sure if it’s worth it, but it’ll be a nice learning experience anyway. The target computer is a computer with a dual-core processor or better with an OpenGL 3.0 ( = DirectX 10) compatible graphics card, if that helps.
Any comment is appreciated! =) Surely someone has to have experience with threads in games! xD