Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Proper Usage of SetThreadAffinityMask

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?

like image 888
Jake Avatar asked May 07 '11 07:05

Jake


People also ask

How do you set an affinity mask?

To set an affinity mask for Processors 3 and 7, you would set the bits as follows: You create the bitmask by enabling the bits that correspond to your processors. For example, the following code snippet shows how to enable bits for Processors 7 and 3: DWORD_PTR mask = (1<< 7) + (1<< 3);

What is affinity thread?

Thread affinity provides a way for an application thread to tell the OS scheduler exactly where its threads can (and would like to) run. The scheduler in turn does not have to spend a lot of time load balancing the system because application threads are already where they need to be.


3 Answers

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.

like image 152
David Heffernan Avatar answered Oct 05 '22 13:10

David Heffernan


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.

like image 39
Alexey Kukanov Avatar answered Oct 05 '22 13:10

Alexey Kukanov


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);
like image 37
wifecooky Avatar answered Oct 05 '22 13:10

wifecooky