|
[In his new Intel sponsored feature, part of the Visual Computing section of Gamasutra, former Insomniac and current Intel staffer Orion Granatir introduces threading by comparing it to networking in games.]
Prior to working at Intel, I worked on PlayStation 3 games at Insomniac Games. Most of the work I did at Insomniac dealt with multiplayer network code. When I came to Intel, I was able to focus on threading, eventually realizing that threading and network programming are similar in several ways.
It can be a challenge to understand threading. Using network programming as a comparison, this article intends to give you an introduction to threading so that by the end you will understand the basics of threading in a Microsoft Windows environment.
Why Thread?
Why thread? That's a good question. Why put up with all
the
challenges that come with threading an application?
In the past, CPUs saw consistent performance gains
because of the increases in frequency. In modern microprocessors, however, this
frequency gain is marginal, and most performance benefits come
from an increased number of cores. Having more cores means the CPU can do more
things at the same time. To maximize performance and features, an application
needs to fully utilize the CPU -- and that
means threading!
Imagine you want to update the artificial intelligence
(AI) for a group of monsters in your game. If you have only one core, all of
those
monsters will need to be processed in order. However, if you have
multiple cores, you can process several monsters at the same time.
More cores, and therefore more threads, means you can
have more monsters in your game. Huzzah!
Threads Are Like Clients
Threads are surprisingly similar to clients, but better.
Clients are separate machines that all work and process independently. Like
clients, cores all work separately and can process independent work. However,
cores don't have to communicate over the slow and scary interwebs. Also, cores
can quickly share data and will never lag out.
So what exactly is a thread?
- A
thread is a series of instructions executed to complete a task.
- Each
process can have multiple threads. Threads share the memory and resources
within a process.
- Just
like clients, threads can work independently.
Here is a process with one thread:
A process can have multiple threads:
Okay, let's see some code. This example creates four
threads: one main thread and three threads that run the PrintLetter function.
CreateThread spawns a new thread. You tell it which
function to run and pass it any associated data. In this example the three
threads run in a loop. The first thread prints 'C', the second prints 'A', and
the third prints 'T'. The main thread will continue to run and do its own work.
Since all threads are running at the same time your output will be a seemingly
random combination of 'C', 'A', and 'T'.
|
How is the best way to determine that a section of code would benefit from threading? I would imagine that in some cases the cost of creating a thread and dealing with synchronisation can be more expensive than regular serial execution. What the best locations/components of a game engine to attempt threading?
Finally, I know that you have developed the Smoke framework which was designed to be parallel from the start, but have you considered implementing threading support in a pre-existing (and open-source) game engine as a proof-of-concept. I think people might benefit from knowing how to integrate good threading functionality into an existing system that was not designed with concurrency in mind. I know of an example that implements a taskpool/scheduler approach into the Quake 3 engine, known as cq3: https://svn.bountysource.com/cq3/trunk/quake3-1.32b/ (by Nick Gildea).
Cheers,
James Munro
Great article again!
Jean-Charles: That would be an example of data decomposition, where each of the worker threads are reading from a thread-safe queue of network messages.
Thanks for the comments ^_^
Download the beta of Parallel Studio here: http://www.intel.com/go/parallel/
Try out Parallel Studio's Amplifier to help locate bottlenecks. These are probably the locations where you'll see the best results for your threading efforts. You can thread most areas of you code, the biggest challenge is determining how much effort it will take to restructure your data for threading. Simple loops that do a lot of calculations and have no data dependencies between iterations is a great place to start.
Good suggestion on threading an open source application... I'll kick the idea around the office.
- Orion
Good question. This is obviously a simplified example. The idea is that all thread will wake up and start pulling messages off the network queue. Once a thread has grabbed a message, it starts processing it. For example, one thread might get a message about damage to a player and start updating that players local data. Another thread might get a message about an explosion and start processing the local physics and animation. This way the threads can do the work in parallel and decrease the total time required to process network messages. I hope this makes sense.
Thanks,
Orion
Thanks for the feedback! Please let me know if there are any areas you'd like me to write about in the future. I'm always interested in hearing things that developers need/want/desire.
I suppose for a beginner it might be useful ... as a lead programmer for a MMO, it didn't help me.
Thanks for you feedback! Sorry about your impressions from GDC :-/ This article (and the associated GDC presentation) was intended for a beginner audience. I'm glad you told me the topics that interest you. I'll work on collateral that helps with the topics you suggested. Please let me know if you have any other thoughts.