[gameprogrammer] Re: Threads and processor affinity

  • From: Matthew Weigel <unique@xxxxxxxxxxx>
  • To: gameprogrammer@xxxxxxxxxxxxx
  • Date: Sun, 01 May 2011 13:34:02 -0500

I seem to have written a lot... short version: keep the number of CPU-bound
threads to less than or equal to the number of cores (possibly counting each
HyperThreaded core double).  Look at cache coherency before worrying about
processor affinity.

On 4/30/2011 12:42 PM, Alan Wolfe wrote:
> Hey Guys,
> 
> I've seen/read in multiple places that people recommend creating at
> max one thread per core of the machine to keep the context switching
> overhead (and such) from degrading performance.

That depends on what the threads are doing.  Separate thread for network
traffic?  Don't bother counting it against the number of cores, most of the
time it's going to be sleeping anyway.  Ditto if you have a separate thread
loading resources from disk on demand; it's going to be sleeping when a)
you're not requesting a resource or b) when it's waiting for the disk to load 
it.

If you have a CPU bound thread, context switches are going to reduce
performance.  Keep in mind, though, that memory access is *also* going to
reduce performance, cache misses will stall the pipeline while the cache lines
are replaced.  I *believe* from behavior I've seen that this can also lead to
core-hopping, as the stalled thread is swapped out for something that wants to
run immediately, and then when the original thread is ready to run again, a
different core happens to be ready to go.

Also note that HyperThreading (or, generically, SMT) makes this more
complicated, as it makes context switching between two (or more... but
generally two) threads on a single core cheaper, particularly when one of the
threads is stalled.  On the other hand, that's only true if the thread tends
to cache miss more; the better cache affinity the thread has, the less HT
helps (and, possibly, the more it hurts).

And yes, if you have more threads than cores *that want to run at the same
time*, there's no telling which core your thread will be running on next time,
it just depends on what core is available the next time the thread is
scheduled to run.  Note also that it's going to be haaaaard to get the total
number of active processes and threads on a modern computer down to the number
of cores, but you can certainly mitigate the extent to which your code is
causing the problem. :-)

> I was wondering, when you do that, does it automatically try and put
> each thread on it's own core or do you have to force processor
> affinity per thread to make that happen?

I think for the most part, modern operating systems continue to run threads on
the same core until it has a reason not to: once a thread is stalled, waiting
for a kernel resource (I/O, probably waiting on a mutex?), or if there's more
threads than cores trying to run.  So... yes, controlling the number of
threads will help.  How much?  That depends on the rest of the factors.

Also, for the most part separate cores within a single CPU share some of the
resources that make core-hopping bad (there are some exceptions where the
multicore "CPU" is really basically two CPUs glued together, rather than an
entire CPU designed to have that many cores) ... and multi-core single-CPU
systems are way more common (at least as PCs) than single-core multi-CPU or
multi-core multi-CPU systems.

All that said... I'm not inclined to set processor affinity on each thread.
How much work are you putting into optimizing for cache coherency?  That's
going to have a lot of impact, but also make processor affinity much more
important to worry about.
-- 
 Matthew Weigel
 hacker
 unique & idempot . ent

---------------------
To unsubscribe go to http://gameprogrammer.com/mailinglist.html


Other related posts: