2011-05-07 352 views
6

有12个内核和12个线程正在运行..我想将1个线程绑定到每个内核。这就是我在每个线程开始时所称的。正确使用SetThreadAffinityMask

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

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

我是否也需要调用SetProcessaffinitymask?

回答

7

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

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

请注意David Heffernan的回答中的注意事项:除非您知道如何使用亲和力,否则您最好不要使用亲和力。除了David已经提到的原因外,我还将在具有不同数量的套接字,内核和超线程的计算机之间添加应用程序可移植性。

+0

通常你会循环在主线程设置亲和力,所以不需要互锁 – 2011-05-07 08:01:19

+0

@大卫:是的,这也是一个选项。我会补充答案。 – 2011-05-07 08:03:43

+0

(1 << core)-1是12位集合 – Jake 2011-05-07 08:09:48

7

您似乎设置所有12个处理器的亲和力,这不是你想要的。

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

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

另外,根据我的经验,手动设置affinity并没有性能优势,有时会更慢。通常这个系统做得很好。

+0

如何设置在主函数的线程关联性?我把它设置在线程函数>,>的开头。第一个参数需要线程处理....我只能调用GetCurrentThread()..是否有另一个函数来获取主函数的句柄? – Jake 2011-05-07 08:13:35

+0

没有想到它..感谢 – Jake 2011-05-07 08:16:45

4

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

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

位掩码通常是64位。一个更通用的解决方案,避免了算术溢出,对那里有超过32个处理器将情况:

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