C++中SetProcessAffinityMask的示例用法是什么?

19

我需要在Windows 7(64位)上针对基准测试将各种C/C++进程固定到机器的特定核心。我的机器有16个内核(2x8)。我试图通过在给定进程的代码中调用SetProcessAffinityMask来实现此目的。假设这是正确的,我不确定如何使用此函数。我已经看过文档,但无法理解第二个参数所需的描述。我在SO或Google上搜索时也没有找到任何示例C/C++用法。

问题1:以一个16核机器(2cpux8)和一个C/C++项目为例,请提供一个说明性示例,说明如何使用SetProcessAffinityMask选择每个16个内核,并解释第二个参数以便我理解。如何将0-15的核心ID转换为等效的位掩码?

问题2:如果一个CPU有2x8个内核,与一个具有16个内核的情况相比,使用方式是否有区别?还是使用方式相同?

非常感谢。这是我目前拥有的。

#include <Windows.h>
#include <iostream>

using namespace std;

int main () {

    HANDLE process = GetCurrentProcess();

    DWORD_PTR processAffinityMask = 0; /// What to do here?

    BOOL success = SetProcessAffinityMask(process, processAffinityMask);

    cout << success << endl;

    return 0;

}
2个回答

19

第二个参数是位掩码,其中设置的位表示该进程可以在该处理器上运行,而清除的位表示它不能。

在您的情况下,要使每个进程在单独的核心上运行,您可以(作为一种可能性)传递一个命令行参数给每个进程一个编号,然后在进程内使用该编号来确定要使用的处理器:

#include <Windows.h>
#include <iostream>

using namespace std;

int main (int argc, char **argv) {
    HANDLE process = GetCurrentProcess();
    DWORD_PTR processAffinityMask = 1 << atoi(argv[1]);

    BOOL success = SetProcessAffinityMask(process, processAffinityMask);

    cout << success << endl;
    return 0;
}

你需要像这样运行:

for %c in (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15) do test %c

杰瑞,还有一个快速问题,假设它仍然与原始问题密切相关。我如何设置多个核心运行? - junkie
1
@junkie:在掩码中设置多个位。例如,使用掩码值为3将允许该进程在处理器0和1上运行。 - Jerry Coffin
1
DWORD_PTR是64位的吗?如果我想使用第65个处理器怎么办? - Hakanai
2
@Trejkaz:是的,它是64位的。目前Windows仅支持最多64个处理器(至少每个节点如此——我需要检查一下NUMA之类的)。 - Jerry Coffin
是的,好吧...最终答案是“如果你想使用处理器65,有一个更新的API可供使用”,这是这些API的典型特征。 - Hakanai
显示剩余5条评论

3

如前所述,它是一个位掩码。如果您的进程或系统没有访问所有核心的权限,您可能希望使用GetProcessAffinityMask的结果。这是我想出来的。

#include <Windows.h>
#include <iostream>
using namespace std; 
 
int main () { 
 
    HANDLE process = GetCurrentProcess(); 
 
    DWORD_PTR processAffinityMask;
    DWORD_PTR systemAffinityMask;

    if (!GetProcessAffinityMask(process, &processAffinityMask, &systemAffinityMask))
        return -1;

    int core = 2; /* set this to the core you want your process to run on */
    DWORD_PTR mask=0x1;
    for (int bit=0, currentCore=1; bit < 64; bit++)
    {
        if (mask & processAffinityMask)
        {
            if (currentCore != core)
            {
                processAffinityMask &= ~mask;
            } else
            {
                if ( !(systemAffinityMask & mask) )
                {
                    cerr << "Core " << core << " not enabled in system." << endl;
                }
            }
            currentCore++;
        }
        mask = mask << 1;
    }

    BOOL success = SetProcessAffinityMask(process, processAffinityMask & systemAffinityMask); 
 
    cout << success << endl; 
 
    return 0; 
 
} 

谢谢。虽然我遇到了与Jerry的答案相同的问题。由于某种原因,当我在您的代码之后进行一些密集计算时,进程似乎会在任务管理器>性能选项卡中超过一个核心。在2-4个核心之间,有100%的峰值。我感觉这里有些不对劲。有什么想法吗? - junkie
没关系,不用在意我说的话。那只是一个误导。我已经在回复Jerry的帖子中做了进一步的解释,请去那里看看。 - junkie
你的代码没有使用 systemAffinityMask 的值吗? - schoetbi
@schoetbi 谢谢你发现了这个问题 - 快速清理,未经测试。 - paquetp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接