Proper Use of SetThreadAffinityMask

There are 12 cores and 12 threads. I want to associate 1 thread with 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 do not know if this was the right way to call it. I'm not sure if I understand how the second parameter works.

Do I also need to call SetProcessaffinitymask?

+6
source share
4 answers

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

For a core 12, your mask (1<<core)-1 contains 0..11 bits, so each thread is allowed to run on any of the 12 cores. Presumably, you wanted each thread to run in a dedicated kernel. To do this, you need each thread to have a unique number between 0 and 11 and set only the corresponding affinity mask bit. Hint: you can use InterlockedIncrement() to get a unique number. Alternatively, if your threads are all running in a loop, a unique number is already known (this is a loop counter), and you can use it, for example. jump to each thread as an argument or establish affinity for new threads in the same cycle.

And please pay attention to the caution in David Heffernan’s answer: if you don’t know how to use closeness to goodness, you better not play with closeness. In addition to the reasons David has already mentioned, I will add portability of applications on computers with different numbers of sockets, cores, and hyperthreads.

+7
source

It seems you are setting proximity to all 12 processors that you do not intend to do.

In the main thread, I would iterate over all 12 threads that establish proximity. Do not establish proximity within a stream, because this requires the stream to know its index, which it often does not need to know. I declare a mask variable and assign it a value of 1. Each time in a cycle, you set the affinity of the stream, and then shift to 1. You must not change the affinity of the process.

A word of caution. Setting proximity is dangerous. If the user changes the affinity for the process, you can get a thread that cannot run on any processor. Be careful.

In addition, my experience shows that manually adjusting proximity does not have performance advantages, and sometimes even slower. Typically, a system does a good job.

+7
source

You can write the code as shown below. GetThreadHandle (i) is a function that receives a handle to each thread.

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

The base mask is usually 64 bits. A more portable solution that avoids arithmetic overflow, for cases when there are more than 32 processors, will be:

 auto mask = (static_cast<DWORD_PTR>(1) << core);//core number starts from 0 auto ret = SetThreadAffinityMask(GetCurrentThread(), mask); 
0
source

Source: https://habr.com/ru/post/887504/


All Articles