有12个内核和12个线程正在运行..我想将1个线程绑定到每个内核。这就是我在每个线程开始时所称的。正确使用SetThreadAffinityMask
int core=12;
SetThreadAffinityMask(GetCurrentThread(),(1<<core)-1);
这就是我所拥有的...我不知道这是否是正确的方式来称呼它。我不确定我是否理解第二参数的工作原理。
我是否也需要调用SetProcessaffinitymask?
有12个内核和12个线程正在运行..我想将1个线程绑定到每个内核。这就是我在每个线程开始时所称的。正确使用SetThreadAffinityMask
int core=12;
SetThreadAffinityMask(GetCurrentThread(),(1<<core)-1);
这就是我所拥有的...我不知道这是否是正确的方式来称呼它。我不确定我是否理解第二参数的工作原理。
我是否也需要调用SetProcessaffinitymask?
SetThreadAffinityMask()
的第二个参数是一个位向量。每一位对应于一个逻辑处理器:一个CPU内核或一个超线程。如果第二个参数中的某位设置为1,则允许线程在相应的核心上运行。
对于core
等于12,您的掩码(1<<core)-1
包含0..11位集,因此每个线程都允许在12个内核中的任何一个上运行。大概你想设置每个线程运行在专用核心上。为此,您需要每个线程都有一个介于0到11之间的唯一编号,并且只设置亲和性掩码的相应位。提示:您可以使用InterlockedIncrement()
来获取唯一编号。或者,如果你的线程都是循环启动的,那么唯一编号已经是已知的(这是循环计数),你可以使用它。作为参数传递给每个线程,或者在同一个循环中为新线程设置亲和性。
请注意David Heffernan的回答中的注意事项:除非您知道如何使用亲和力,否则您最好不要使用亲和力。除了David已经提到的原因外,我还将在具有不同数量的套接字,内核和超线程的计算机之间添加应用程序可移植性。
您似乎设置所有12个处理器的亲和力,这不是你想要的。
我会在主线程中遍历所有12个线程设置关联。不要在线程中设置亲和力,因为这需要线程知道它通常不需要知道的索引。我将声明一个掩码变量并为其赋值1.每次循环时,您都设置线程亲和性,然后移位1.不应该更改进程亲和性。
一句谨慎。设置亲和力是危险的。如果用户更改进程关联性,那么最终可能会有一个无法在任何处理器上运行的线程。小心。
另外,根据我的经验,手动设置affinity并没有性能优势,有时会更慢。通常这个系统做得很好。
你可以编写下面的代码。 GetThreadHandle(i)是获取每个线程句柄的函数。
int core = 12;
for(int i=0; i<core; i++)
SetThreadAffinityMask(GetThreadHandle(i), 1<<i);
位掩码通常是64位。一个更通用的解决方案,避免了算术溢出,对那里有超过32个处理器将情况:
auto mask = (static_cast<DWORD_PTR>(1) << core);//core number starts from 0
auto ret = SetThreadAffinityMask(GetCurrentThread(), mask);
通常你会循环在主线程设置亲和力,所以不需要互锁 – 2011-05-07 08:01:19
@大卫:是的,这也是一个选项。我会补充答案。 – 2011-05-07 08:03:43
(1 << core)-1是12位集合 – Jake 2011-05-07 08:09:48