Components
File: Core-Affine Thread Pool for XNA
- Uploaded:
- September.17.09
- Modified:
- September.17.09
- File Size:
- 9 KB
- Downloads:
- 670
- Version
- 1.0
A custom thread pool which creates one thread for each available CPU core. This avoids
bottlenecks on the XBox 360, where all threads (including the .NET ThreadPool)
run on core 1 unless explicitly assigned to another core. On Windows, it exposes similar
behavior by suggesting a core to the OS instead of using hard affinity.
Details
If you try to speed up mass calculations using threads on the XBox 360, you might discover that
all your threads are running on core 1. Even the entire ThreadPool seems to use only
one hardware thread, even though the XBox 360 supposedly has 6 of them (of which XNA developers
can use 4).
This is so because threads need to be assigned to a different hardware thread explicitly. Creating
threads is a time-consuming process, so instead of letting each multi-threaded component in my
games create its own four threads, I created a clone of the ThreadPool which made use
of the additional cores.
To expose comparable behavior on Windows, one thread is created for each logical CPU (meaning it
would create 8 threads on a quad-core CPU with hyper-threading). Instead of using hard affinity,
my thread pool will only suggest a core. This allows the thread scheduler to still do its work
while not drastically altering the behavior of the AffineThreadPool.
Fixing threads to a CPU core is a bad idea on Windows because you're essentially circumventing the OS' thread scheduler. This can very well lead to worse performance - imagine core 1 is busy doing some OS bookkeeping and you cleverly distribute work across the whole CPU. What happens?
All cores finish their work but the thread that's fixed to core 1 is still waiting. And even though the other cores are free and could take over, the thread scheduler can't help you because you fixed the thread to core 1. See here for another description of the problem: Parallelism and CPU Affinity.
Example
The AffineThreadPool works almost exactly like a trimmed-down version of .NET's
ThreadPool
class. On the PC, it's marginally slower than the real ThreadPool (even though it's
the tightest implementation I could come up with that still works on the XBox 360 - hats off to
the ThreadPool developers! .NET 4.0 will make it even faster, by the way.)
Unhandled exceptions reaching the AffineThreadPool are ignored by default, but you
can trap them and add an assertion or whatever you'd like to do by setting a delegate in the
AffineTheadPool class. I would have loved to use
AppDomain.UnhandledException, but there's no (clean) way to fire that event
from code.
Features
- 100% unit test coverage for everything
- Works on the XBox 360 and PC
- Should be easy to port to the compact framework
- Allows easy usage of the XBox 360's cores
- Comparable behavior across platforms
- On the PC, suggests core, but doesn't enforce
This class is part of the Nuclex.Support library from the Nuclex Framework.
You can find the most recent release of the code on the framework's CodePlex site:
http://nuclexframework.codeplex.com/