none
Setting a managed thread's processor affinity RRS feed

  • Question

  • Hi,

    In short, Is there a way to set a managed thread's processor affinity?

    I have 3 threads in my applications, and I want to allocate them to each of the CPU's two cores (one thread to one core, two threads to the other).  I'm aware of System.Diagnostics.Process.GetCurrentProcess().Threads[x].ProcessorAffinity, but I don't think I can match the thread in the collection with either of my managed threads.

    Any ideas?

    Thanks in advance,
      Ury
    Wednesday, May 7, 2008 12:54 PM

Answers

  • Technically there is a way to get the actual OS thread id for a managed thread, but that is a deprecated API and it won't actually give you the proper results if you're not running under the default CLR host (AppDomain.GetCurrentThreadId()).  The reason is that the correlation between CLR threads and OS threads is not guaranteed (as of CLR 2.0).

     

    This means two things effectively:

    1. A single OS thread can host multiple CLR threads (e.g. using fibers or other cooperative scheduling mechanisms)

    2. A single CLR thread can jump between multiple OS threads

     

    In the default CLR host, CLR threads and OS threads are essentially the same, and therefore you can safely ignore this warning, at least with the current CLR version.  However, if you're running under a custom host (such as SQL Server 2005 or your own), then you should be aware of the fact that the OS thread id doesn't mean much.

     

    By the way, if you are very concerned about keeping your CLR thread on the same OS thread, then you can call Thread.BeginThreadAffinity and the CLR thread will be tied to the OS thread from that moment on.

     

    Generally, I wouldn't be fooling around with CPU affinity unless I am absolutely sure that I am smarter than the OS scheduler.  Are you smarter than the OS scheduler?  Read this first: http://blogs.microsoft.co.il/blogs/sasha/archive/2008/04/20/parallelism-and-cpu-affinity.aspx

    Wednesday, May 7, 2008 4:25 PM
  • Assigning CPU affinities to your threads in this scenario is unlikely to help.  If the OS were able to schedule your threads so that your application uses 100% CPU, then it would have happened.  Granted that your application is the only thing running on the machine, and that your processing is CPU-bound, and that the queue is still getting filled, it seems that either the producer thread is enqueueing items at a faster rate than the consumer thread is capable of processing them, and/or that you're not getting 100% CPU because of heavy locking (contention) on the queue.  If the work items are very small, then the contention and context switching that it introduces could account for a large % of the CPU time.  If that's the case I suggest you try batching the work items before enqueueing them.
    Friday, May 9, 2008 8:31 AM

All replies

  • Technically there is a way to get the actual OS thread id for a managed thread, but that is a deprecated API and it won't actually give you the proper results if you're not running under the default CLR host (AppDomain.GetCurrentThreadId()).  The reason is that the correlation between CLR threads and OS threads is not guaranteed (as of CLR 2.0).

     

    This means two things effectively:

    1. A single OS thread can host multiple CLR threads (e.g. using fibers or other cooperative scheduling mechanisms)

    2. A single CLR thread can jump between multiple OS threads

     

    In the default CLR host, CLR threads and OS threads are essentially the same, and therefore you can safely ignore this warning, at least with the current CLR version.  However, if you're running under a custom host (such as SQL Server 2005 or your own), then you should be aware of the fact that the OS thread id doesn't mean much.

     

    By the way, if you are very concerned about keeping your CLR thread on the same OS thread, then you can call Thread.BeginThreadAffinity and the CLR thread will be tied to the OS thread from that moment on.

     

    Generally, I wouldn't be fooling around with CPU affinity unless I am absolutely sure that I am smarter than the OS scheduler.  Are you smarter than the OS scheduler?  Read this first: http://blogs.microsoft.co.il/blogs/sasha/archive/2008/04/20/parallelism-and-cpu-affinity.aspx

    Wednesday, May 7, 2008 4:25 PM
  •  

    Thanks Sasha.

    This is very enlightning.

     

    Maybe I should take one step back: my goal is not to outsmart the CPU but to allocate more CPU time to my application.

     

    My image-processing app is extremely CPU-intensive.  It's a basic producer-consumer multi-thread architecture and I noticed that the queue is sometimes filled because the consumer can't handle the incoming images.  At the same time, the CPU workload is considerably less than 100%.  I know there could be many reasons for that.  I have profiled the application, reconsidered the thread and process priorities and the locking mechanisms.  It still looks like the OS is *unwilling* to allocate more CPU to the application.  I thought that by forcing the OS to distribute the 2 processing thread + 1 main/GUI thread between the two cores I might get better results.

     

    Any thoughts?

    Regards,

      Ury

    Friday, May 9, 2008 7:57 AM
  • Assigning CPU affinities to your threads in this scenario is unlikely to help.  If the OS were able to schedule your threads so that your application uses 100% CPU, then it would have happened.  Granted that your application is the only thing running on the machine, and that your processing is CPU-bound, and that the queue is still getting filled, it seems that either the producer thread is enqueueing items at a faster rate than the consumer thread is capable of processing them, and/or that you're not getting 100% CPU because of heavy locking (contention) on the queue.  If the work items are very small, then the contention and context switching that it introduces could account for a large % of the CPU time.  If that's the case I suggest you try batching the work items before enqueueing them.
    Friday, May 9, 2008 8:31 AM
  • Thanks Sasha.

    Queue locking isn't supposed to take "that long".  I'll try to figure this out.

    Friday, May 9, 2008 10:27 AM