What are cores and threads?
I have been programming for a couple of years now, but recenty on here I have been seeing some sujects related to "multi-threaded game programming". I know what threads are, but I don't understand how it relates to game programming. Can someone explain, and maybe give me a practical example? I don't want any holes in my knowledge. Thanks!
When you have a game with only one thread then everything has to be done on that thread which can potentially slow things down. By using threads you can logically separate things such as AI processing and Graphical Rendering from each-other on separate threads while keeping them part of the same program. You can also take advantage of multi-core processors and also gain the increase in speed from how an OS takes care of it's threads.
It is a great idea for games though small games can get away without it.
It is a great idea for games though small games can get away without it.
Computers run instructions on a CPU(Central Processing Unit) which is also called a core (note: this is a simplified view, I'm not getting into technically bits). A core can only run one program at a time. Programs are seperated into threads, as in "threads of execution".
The computer loads a thread into the core, executes it for a while, switches to another thread, executes it for a while, wash rinse repeat. This is how your computer appears to run more than one program at a time, even though it can only execute one thread per core.
On multicore systems, each core can handle one thread at a time, but you cannot run one thread on more than one core at the same time. If you split your program up into multiple threads, then many of your threads can run on the cores all at once.
Example: You have a physics thread and a network thread on a two core system. Core #1 can run your physics calculations, and at the same time Core #2 can run you network system.
If you only had one core, your physics code would run and then when it was done your network code would run.
Here's a little more practical information for you.
I'll assume you're using a language like C.
Every program has a least one thread. main() is executed using that thread. In your first thread, you can call an API with a function pointer, and the function pointed to will execute in a new thread. This thread may be executed on any core in the system, potentially at the same time your first thread is executing in another core.
It works like that for any number of threads and cores. Any thread may execute in any core at any time, as long as there is only one thread on a core and at most one core executing any given thread.
I'm sorry if I am explaining something you already know, but I don't know what kind of experience you have.
Hope this helps.
-Koobs
[Edited by - Koobs on February 18, 2008 9:02:58 PM]
The computer loads a thread into the core, executes it for a while, switches to another thread, executes it for a while, wash rinse repeat. This is how your computer appears to run more than one program at a time, even though it can only execute one thread per core.
On multicore systems, each core can handle one thread at a time, but you cannot run one thread on more than one core at the same time. If you split your program up into multiple threads, then many of your threads can run on the cores all at once.
Example: You have a physics thread and a network thread on a two core system. Core #1 can run your physics calculations, and at the same time Core #2 can run you network system.
If you only had one core, your physics code would run and then when it was done your network code would run.
Here's a little more practical information for you.
I'll assume you're using a language like C.
Every program has a least one thread. main() is executed using that thread. In your first thread, you can call an API with a function pointer, and the function pointed to will execute in a new thread. This thread may be executed on any core in the system, potentially at the same time your first thread is executing in another core.
It works like that for any number of threads and cores. Any thread may execute in any core at any time, as long as there is only one thread on a core and at most one core executing any given thread.
I'm sorry if I am explaining something you already know, but I don't know what kind of experience you have.
Hope this helps.
-Koobs
[Edited by - Koobs on February 18, 2008 9:02:58 PM]
To answer the question in the topic first.
A multicore cpu is basically multiple cpus welded together on a single die.
From an OS and Applications point of view it works just like traditional multiprocessor systems however.
On a single cpu / single core system it is impossible to actually run more than one process at the time, the OS therefore schedules all processes and switches rapidly between them (making it appear like they are all running at the same time). , with more cpus or cores the OS will run more processes in parallel and thus improving performance.
a thread is essentially a process that exists within another process, the OS will schedule threads just like it does with processes, threads however are not isolated like processes are (All threads within a process can read and write to the same memory locations).
a very simple use of threads in games is to prevent long running functions from freezing the game entierly, if we take a game such as chess for example you wouldn't want the game to freeze entierly while the computer figures out its next move, you can also use it to load data in the background while the game is running (useful for games with large open worlds).
The key problem with threads is that you:
1) Don't know exactly when a given instruction is executed
Lets say that thread A executes print("a"); print("b"); etc while Thread B executes print("1"); print("2"); etc.
on one run you could get the result ab12 on another you could get 12ab 1ab2 or 1a2b or something similar.
Once your threads start modifying data things get a bit hairy, you will need to make sure that one thread doesn't modify data that another thread is using or the results can be quite unpredictable.
To combat this you will be forced to lock your threads from time to time, this is normally done by using mutually exclusive access flags (or a mutex or semaphore)
For example if thread A wants to use [CoolData] it first tries to lock [CoolMutex] , if its allready locked it waits until it can be locked again.
Once it is locked it can freely access [CoolData] do its thing with it, and then unlock [CoolMutex] so that another thread can do the same.
All this waiting drastically reduces the performance gain though so very few applications will get anywhere close to twice the performance just by doubling the number of cpus or cores.
A multicore cpu is basically multiple cpus welded together on a single die.
From an OS and Applications point of view it works just like traditional multiprocessor systems however.
On a single cpu / single core system it is impossible to actually run more than one process at the time, the OS therefore schedules all processes and switches rapidly between them (making it appear like they are all running at the same time). , with more cpus or cores the OS will run more processes in parallel and thus improving performance.
a thread is essentially a process that exists within another process, the OS will schedule threads just like it does with processes, threads however are not isolated like processes are (All threads within a process can read and write to the same memory locations).
a very simple use of threads in games is to prevent long running functions from freezing the game entierly, if we take a game such as chess for example you wouldn't want the game to freeze entierly while the computer figures out its next move, you can also use it to load data in the background while the game is running (useful for games with large open worlds).
The key problem with threads is that you:
1) Don't know exactly when a given instruction is executed
Lets say that thread A executes print("a"); print("b"); etc while Thread B executes print("1"); print("2"); etc.
on one run you could get the result ab12 on another you could get 12ab 1ab2 or 1a2b or something similar.
Once your threads start modifying data things get a bit hairy, you will need to make sure that one thread doesn't modify data that another thread is using or the results can be quite unpredictable.
To combat this you will be forced to lock your threads from time to time, this is normally done by using mutually exclusive access flags (or a mutex or semaphore)
For example if thread A wants to use [CoolData] it first tries to lock [CoolMutex] , if its allready locked it waits until it can be locked again.
Once it is locked it can freely access [CoolData] do its thing with it, and then unlock [CoolMutex] so that another thread can do the same.
All this waiting drastically reduces the performance gain though so very few applications will get anywhere close to twice the performance just by doubling the number of cpus or cores.
Thanks for the answers guys! Know I finally also understand why some functions have to be manualy locked. So one more thing: if you're running a dual or quad-core processor, how do you access the separate cores to create a multi-threaded game? Sorry if that question isn't clear, I can't think of another way to say it.
If you create more than one thread it will run on the next available processor. You don't have to do anything outside of writing multi threaded code. If you write an app that starts 4 threads on a quad core processor the threads will share the four cores. If you run it on a dual core two will run at a time and switch off with one of the other threads that are waiting to run. If you run a program with two threads on a quad core only half the processors will be used.
Quote:Original post by Renegader_bj
Thanks for the answers guys! Know I finally also understand why some functions have to be manualy locked. So one more thing: if you're running a dual or quad-core processor, how do you access the separate cores to create a multi-threaded game? Sorry if that question isn't clear, I can't think of another way to say it.
If you mean 'how to start the threads', well this mainly depend on which language are you using. Most modern language (Java and .net like C#, but also Python and so on) expose libraries to handle threads. Google for java and threads for examples.
C++ doesn't support threads natively, but external libraries exists to accomplish the task: if you are interested, google for boost:thread and OpenMP. The first is a free library that gives you all the tools you need to create multithreading applications, while OpenMP is a standard that must be supported by the compiler (both Microsoft Visual C++ an gcc support it) that consists in a few instruction to make the compiler able to split the code into multiple theads (i.e. making a for loop able to execute on more thread in the same time: if the cicles are not correlated, then you can speed up it execution by n times, with n the number of cores of your CPU)...
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement