我已经编写了一个小的测试程序,在其中我尝试使用Windows API调用NUMA将线程锁定到单个SetThreadAffinityMask节点。我使用GetNumaNodeProcessorMask API调用检索节点的CPU位掩码,然后将该位掩码与GetCurrentThread返回的线程句柄一起传递给SetThreadAffinityMask。下面是我的代码的一个大大简化的版本:
// Inside a function called from a boost::thread
unsigned long long nodeMask = 0;
GetNumaNodeProcessorMask(1, &nodeMask);
HANDLE thread = GetCurrentThread();
SetThreadAffinityMask(thread, nodeMask);
DoWork(); // make-work function当然,我会检查API调用是否在我的代码中返回0,并且我还打印出了NUMA节点掩码,这正是我所期望的。我还遵循了其他地方给出的建议,打印出了第二个相同的SetThreadAffinityMask调用返回的掩码,它与节点掩码匹配。
但是,在DoWork函数执行时观察资源监视器,工作将在所有核心之间进行划分,而不仅仅是表面上它绑定到的那些核心。在使用SetThreadAffinityMask时,有没有什么我可能遗漏的问题?我运行的是64位Windows7专业版,DoWork函数包含一个与OpenMP并行化的循环,它对三个非常大的数组的元素执行操作(这三个数组加在一起仍然可以放在节点中)。
编辑:对David Schwartz给出的答案进行扩展,在Windows上,任何用OpenMP产生的线程都不会继承产生它们的线程的亲和力。问题出在这点上,而不是SetThreadAffinityMask。
发布于 2012-01-24 08:10:01
您是否确认其亲和性掩码运行在另一个numa节点的核心上的特定线程?否则,它就像预期的那样工作。您将在一个线程上设置处理器掩码,然后观察一组线程的行为。
https://stackoverflow.com/questions/8980393
复制相似问题