[gameprogrammer] Re: Threads and processor affinity

  • From: Charlie Lobo <charlie.lobo@xxxxxxxxx>
  • To: gameprogrammer@xxxxxxxxxxxxx
  • Date: Mon, 2 May 2011 00:17:35 -0500

I'll agree with Brian here: you are not the only program running and have no
idea what is going on in the rest of the machine.
I personally believe that you shouldn't care about this unless you are
having a number of complex, CPU bound threads an order or two of magnitudes
more than the number of expected CPUs.
If you do have this situation you should still not try to enforce having
processes run on a specific CPU or such. Again you have no idea how many
other threads and processes are running, you are just hoping that your
program won't have so many threads that the context switching overhead
becomes huge. Context switching is unavoidable on most OS (exception being
OS that don't allow parallel proccesing) since even a console has to process
online conections and other services, and you cannot and most not assume the
number of threads this take (a single patch could ruin it). Also because you
can't gaurantee that all threads will be available (disk operations and
such) you might have idle cores and just waste space. Context switching is
pretty heavy, but then again so is calling a function (GOSUB) compared to a
simple GOTO, it's not a problem unless it's abused.

With all this in mind, there are a few solutions:
A task based system
A tasklet/cofunction system

In both cases you do create a "task handler" which has a bunch of threads,
the number being the number of CPU cores as reported by the OS. The system
recieves "tasks" which are instructions to run a certain function. The
program then delegates a task to a freed up thread. You'd want the threads
protected by a semaphore, which allows for multiple resources of which
anyone could work, request queues, and priotization of the resource
requests.
We still have the problem that some tasks would lock up the thread while
waiting for some resource (network response, disk operation, etc.etc.). It's
very probable that most threads could lock up for some time in this
operations causing considerable lag, since you could do other, CPU bound
operations. So we add the tasks the ability to "terminate" early, this is a
certain points they go to sleep, until they recieve a signal that the
non-CPU-bound operation is done, at which point they add themselves back to
the queue (maybe with a boost in priority) to finish the job. This could be
implemented with a careful framework using functors, though cofunctions are
much more powerful for this, depends on what your plataform allows.

So in conclusion:
Don't care about the number of threads unless you are making a number of
threads a couple orders of magnitude greater than the CPU cores (aka making
200 threads).
Do you really need to do all this in parallel? Why not just iterate through
a few of this things in good old fashioned linear programming and reduce the
number of threads?
If still you do have to, you are going to rebuild your own context
switching, which means having to reinvent the wheel, and you are not
guaranteed to be faster than your OS. Look around, there probably is a
library that already does that.

On Sun, May 1, 2011 at 12:02 PM, Brian Barrett <brian.ripoff@xxxxxxxxx>wrote:

> A good OS will move processor hungry threads onto idle cores. If it
> does not, then maybe manually managing the affinity is a solution. A
> note though: manually managing affinity can be a bad solution, what if
> all programs did this! They would probably all end up on the first few
> cores, with any others lying idle. Unless you see evidence of a
> particular OS mismanaging allocation, I would be hesitant to mess
> around with affinity.
>
> On consoles I imagine it is much more useful, my understanding is that
> console operating systems are simpler and you aren't competing with
> other processes for the available cores.
>
> On 30 April 2011 18:42, Alan Wolfe <alan.wolfe@xxxxxxxxx> 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.
> >
> > 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'm most curious about windows PCs but if OS matters, does linux / BSD
> > behave differently?  How about on the 360 or PS3 (excluding the SPUs
> > hehe)?
> >
> > Thanks!
> >
>
> ---------------------
> To unsubscribe go to http://gameprogrammer.com/mailinglist.html
>
>
>

Other related posts: