11

There are 12 cores, and 12 threads running..I want to bind 1 thread to each core. this is what I call at the beginning of each thread.

int core=12;
SetThreadAffinityMask(GetCurrentThread(),(1<<core)-1);

This is what I have...I don't know if this would be the proper way to call it. I'm not sure if i'm understanding how the 2nd parameter works..

Do i also need to call SetProcessaffinitymask as well?

Jake
  • 2,877
  • 8
  • 43
  • 62

4 Answers4

9

The second parameter to SetThreadAffinityMask() is a bit vector. Each bit corresponds to a logical processor: a CPU core or a hyper-thread. If a bit in the second parameter is set to 1, the thread is allowed to run on the corresponding core.

For core equal to 12, your mask (1<<core)-1 contains 0..11 bits set, so every thread is allowed to run on any of the 12 cores. Presumably you wanted to set each thread to run on a dedicated core. For this, you need each thread to have a unique number between 0 and 11, and set only the corresponding bit of the affinity mask. Hint: you may use InterlockedIncrement() to get the unique number. Alternatively, if your threads are all started in a loop, the unique number is already known (it's the loop trip count) and you may use it, e.g. pass to each thread as an argument, or set affinity for new threads in that same loop.

And please, pay attention to the caution in David Heffernan's answer: unless you know how to use affinity for good, you better do not play with affinity. In addition to the reasons David already mentioned, I will add application portability across computers having different number of sockets, cores, and hyper-threads.

Alexey Kukanov
  • 12,479
  • 2
  • 36
  • 55
8

You appear to be setting affinity to all 12 processors which is not what you intend.

I would, in the main thread, loop over all 12 threads setting affinity. Don't set the affinity inside the thread because that requires the thread to know its index which it often does not need to know. I'd declare a mask variable and assign it the value 1. Each time round the loop you set the thread affinity and then shift by 1. You should not change the process affinity.

A word of caution. Setting affinity is dangerous. If the user changes process affinity then you may end up with a thread that is not able to run on any processor. Be careful.

Also, it is my experience that manually setting affinity has no performance benefits and sometimes is slower. Usually the system does a good job.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • How do you set the thread affinity in the main function? I have it set at the beginning of the thread functions >,>. The first parameter requires the thread handle....I can only call GetCurrentThread()..is there another function to get the handle from the main function? – Jake May 07 '11 at 08:13
6

You could write code like below. GetThreadHandle(i) is the function that get the handle of each thread.

int core = 12;
for(int i=0; i<core; i++)  
  SetThreadAffinityMask(GetThreadHandle(i), 1<<i);
wifecooky
  • 83
  • 1
  • 4
0

The bitmask is typically 64 bit. A more portable solution that avoids arithmetic overflow, for cases where there are more than 32 processors would be:

auto mask = (static_cast<DWORD_PTR>(1) << core);//core number starts from 0
auto ret = SetThreadAffinityMask(GetCurrentThread(), mask);
Mikhail
  • 7,749
  • 11
  • 62
  • 136