【问题标题】:Example usage of SetProcessAffinityMask in C++?C++ 中 SetProcessAffinityMask 的示例用法?
【发布时间】:2012-09-29 23:51:31
【问题描述】:

我需要将各种 c/c++ 进程固定到机器上的特定内核,以便仅在 Windows 7 64 位上进行基准测试。我的机器有 16 个内核 (2x8)。我试图通过从给定进程的代码中调用 SetProcessAffinityMask 来做到这一点。假设这是正确的,我不确定如何准确使用此功能。我已经看过文档,但无法理解它对第二个参数的描述。我也没有在 SO 或 Google 上搜索过任何示例 c/c++ 用法。

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

问题 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;

}

【问题讨论】:

    标签: c++ windows


    【解决方案1】:

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

    在您的情况下,要让每个进程在单独的内核上运行,您可以(出于一种可能性)传递一个命令行参数,为每个进程提供一个数字,并在进程内使用该数字来确定要使用的处理器:

    #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
    

    【讨论】:

    • 谢谢。你的意思是在最后一个代码 sn-p 中上升到 15 吗?
    • 好的np。所以我对此进行了测试。在您的代码之后,我添加了代码来创建一个大小为 10^8 的 int 数组,用随机数填充它并对其进行排序以占用一些 cpu 时间。当我在选择一个特定内核的情况下运行此主方法时,即使 setprocessaffinitymask 返回非零值,该进程似乎在任务管理器中占用 2-3 个内核 > 性能可视化,从我启动主方法时 100% 利用率峰值判断.知道为什么这可能不起作用还是我测试错了?如果你愿意,我可以发布更新的代码。
    • @junkie:在掩码中设置多个位。例如,使用掩码值 3 将使进程在处理器 0 和 1 上运行。
    • DWORD_PTR 是 64 位的吗?如果我想使用 65 号处理器怎么办?
    • @Trejkaz:是的,它是 64 位的。 Windows 目前仅支持最多 64 个处理器(至少每个节点——我必须检查以确保 NUMA 等)。
    【解决方案2】:

    如前所述,它是一个位掩码。您可能希望使用 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; 
     
    } 
    

    【讨论】:

    • 谢谢。尽管我对杰瑞的回答有同样的问题。出于某种原因,当我在您的代码之后进行一些密集计算时,进程似乎在任务管理器 > 性能选项卡中的多个核心上出现峰值。 2-4 个内核之间的某个地方以 100% 的速度飙升。我觉得这里有些不对劲。有什么想法吗?
    • 没关系。忽略我说的。这是一条红鲱鱼。我已经进一步解释了杰里的帖子。请在那里看看。
    • 你的代码没有使用systemAffinityMask的值?
    • @schoetbi 感谢您发现这一点 - 快速清理,未经测试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-14
    • 2016-09-29
    • 1970-01-01
    • 2012-02-23
    • 2010-12-25
    • 2016-01-02
    • 2010-09-12
    相关资源
    最近更新 更多