正确使用SetThreadAffinityMask

发布于 2024-11-05 14:35:51 字数 259 浏览 0 评论 0 原文

有 12 个核心,运行 12 个线程。我想为每个核心绑定 1 个线程。这就是我在每个线程的开头所说的。

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

这就是我所拥有的......我不知道这是否是正确的调用方式。我不确定我是否理解第二个参数的工作原理。

我是否还需要调用 SetProcessaffinitymask ?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

讽刺将军 2024-11-12 14:35:51

SetThreadAffinityMask() 的第二个参数是位向量。每一位对应一个逻辑处理器:一个CPU核心或一个超线程。如果第二个参数中的某个位设置为1,则允许线程在相应的核心上运行。

对于等于 12 的 core,掩码 (1< 包含 0..11 位集,因此每个线程都可以在任何12 核。大概您希望将每个线程设置为在专用核心上运行。为此,您需要每个线程都有一个 0 到 11 之间的唯一编号,并且仅设置关联掩码的相应位。提示:您可以使用InterlockedIncrement()来获取唯一编号。或者,如果您的线程都是在循环中启动的,则唯一编号是已知的(它是循环行程计数),您可以使用它,例如作为参数传递给每个线程,或者为同一循环中的新线程设置亲和力。

请注意大卫·赫弗南 (David Heffernan) 回答中的警告:除非你知道如何利用亲和力做好事,否则最好不要玩弄亲和力。除了 David 已经提到的原因之外,我还将在具有不同数量的套接字、内核和超线程的计算机之间添加应用程序可移植性。

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.

此刻的回忆 2024-11-12 14:35:51

您似乎正在设置与所有 12 个处理器的关联性,这不是您想要的。

我会在主线程中循环设置亲和力的所有 12 个线程。不要在线程内设置关联性,因为这需要线程知道其索引,而它通常不需要知道。我会声明一个掩码变量并为其分配值 1。每次循环时,您都会设置线程关联性,然后移动 1。您不应更改进程关联性。

一句警告。设置亲和力是危险的。如果用户更改进程关联性,那么您最终可能会得到一个无法在任何处理器上运行的线程。当心。

另外,根据我的经验,手动设置亲和力没有性能优势,有时甚至更慢。通常该系统做得很好。

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.

随遇而安 2024-11-12 14:35:51

您可以编写如下代码。
GetThreadHandle(i) 是获取每个线程句柄的函数。

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

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);
迷迭香的记忆 2024-11-12 14:35:51

位掩码通常为 64 位。对于超过 32 个处理器的情况,避免算术溢出的更便携的解决方案是:

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

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文