C++ 以编程方式查找机器上的内核数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/150355/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:15:29  来源:igfitidea点击:

Programmatically find the number of cores on a machine

c++c

提问by hazzen

Is there a way to determine how many cores a machine has from C/C++ in a platform-independent way? If no such thing exists, what about determining it per-platform (Windows/*nix/Mac)?

有没有办法以独立于平台的方式从 C/C++ 确定一台机器有多少个内核?如果不存在这样的东西,那么如何确定每个平台(Windows/*nix/Mac)?

回答by paxos1977

C++11

C++11

#include <thread>

//may return 0 when not able to detect
const auto processor_count = std::thread::hardware_concurrency();

Reference: std::thread::hardware_concurrency

参考:std::thread::hardware_concurrency



In C++ prior to C++11, there's no portable way. Instead, you'll need to use one or more of the following methods (guarded by appropriate #ifdeflines):

在 C++11 之前的 C++ 中,没有可移植的方式。相反,您需要使用以下一种或多种方法(由适当的#ifdef行保护):

  • Win32

    SYSTEM_INFO sysinfo;
    GetSystemInfo(&sysinfo);
    int numCPU = sysinfo.dwNumberOfProcessors;
    
  • Linux, Solaris, AIX and Mac OS X >=10.4 (i.e. Tiger onwards)

    int numCPU = sysconf(_SC_NPROCESSORS_ONLN);
    
  • FreeBSD, MacOS X, NetBSD, OpenBSD, etc.

    int mib[4];
    int numCPU;
    std::size_t len = sizeof(numCPU); 
    
    /* set the mib for hw.ncpu */
    mib[0] = CTL_HW;
    mib[1] = HW_AVAILCPU;  // alternatively, try HW_NCPU;
    
    /* get the number of CPUs from the system */
    sysctl(mib, 2, &numCPU, &len, NULL, 0);
    
    if (numCPU < 1) 
    {
        mib[1] = HW_NCPU;
        sysctl(mib, 2, &numCPU, &len, NULL, 0);
        if (numCPU < 1)
            numCPU = 1;
    }
    
  • HPUX

    int numCPU = mpctl(MPC_GETNUMSPUS, NULL, NULL);
    
  • IRIX

    int numCPU = sysconf(_SC_NPROC_ONLN);
    
  • Objective-C (Mac OS X >=10.5 or iOS)

    NSUInteger a = [[NSProcessInfo processInfo] processorCount];
    NSUInteger b = [[NSProcessInfo processInfo] activeProcessorCount];
    
  • 赢32

    SYSTEM_INFO sysinfo;
    GetSystemInfo(&sysinfo);
    int numCPU = sysinfo.dwNumberOfProcessors;
    
  • Linux、Solaris、AIX 和 Mac OS X >=10.4(即 Tiger 以上)

    int numCPU = sysconf(_SC_NPROCESSORS_ONLN);
    
  • FreeBSD、MacOS X、NetBSD、OpenBSD 等。

    int mib[4];
    int numCPU;
    std::size_t len = sizeof(numCPU); 
    
    /* set the mib for hw.ncpu */
    mib[0] = CTL_HW;
    mib[1] = HW_AVAILCPU;  // alternatively, try HW_NCPU;
    
    /* get the number of CPUs from the system */
    sysctl(mib, 2, &numCPU, &len, NULL, 0);
    
    if (numCPU < 1) 
    {
        mib[1] = HW_NCPU;
        sysctl(mib, 2, &numCPU, &len, NULL, 0);
        if (numCPU < 1)
            numCPU = 1;
    }
    
  • 用户体验

    int numCPU = mpctl(MPC_GETNUMSPUS, NULL, NULL);
    
  • 爱丽丝

    int numCPU = sysconf(_SC_NPROC_ONLN);
    
  • Objective-C(Mac OS X >=10.5 或 iOS)

    NSUInteger a = [[NSProcessInfo processInfo] processorCount];
    NSUInteger b = [[NSProcessInfo processInfo] activeProcessorCount];
    

回答by Ferruccio

This functionality is part of the C++11 standard.

此功能是 C++11 标准的一部分。

#include <thread>

unsigned int nthreads = std::thread::hardware_concurrency();

For older compilers, you can use the Boost.Threadlibrary.

对于较旧的编译器,您可以使用Boost.Thread库。

#include <boost/thread.hpp>

unsigned int nthreads = boost::thread::hardware_concurrency();

In either case, hardware_concurrency()returns the number of threads that the hardware is capable of executing concurrently based on the number of CPU cores and hyper-threading units.

在任一情况下,hardware_concurrency()根据 CPU 内核和超线程单元的数量返回硬件能够并发执行的线程数。

回答by macbirdie

OpenMPis supported on many platforms (including Visual Studio 2005) and it offers a

许多平台(包括 Visual Studio 2005)都支持OpenMP,它提供了一个

int omp_get_num_procs();

function that returns the number of processors/cores available at the time of call.

返回调用时可用的处理器/内核数的函数。

回答by Head Geek

If you have assembly-language access, you can use the CPUID instruction to get all sorts of information about the CPU. It's portable between operating systems, though you'll need to use manufacturer-specific information to determine how to find the number of cores. Here's a document that describes how to do it on Intel chips, and page 11 of this onedescribes the AMD specification.

如果您有汇编语言访问权限,则可以使用 CPUID 指令来获取有关 CPU 的各种信息。它在操作系统之间是可移植的,但您需要使用特定于制造商的信息来确定如何找到内核数。下面是描述如何做到这一点英特尔芯片的文档,以及第11页这一个介绍AMD规范。

回答by Dirk-Jan Kroon

(Almost) Platform Independent function in c-code

(几乎)c 代码中的平台独立函数

#ifdef _WIN32
#include <windows.h>
#elif MACOS
#include <sys/param.h>
#include <sys/sysctl.h>
#else
#include <unistd.h>
#endif

int getNumCores() {
#ifdef WIN32
    SYSTEM_INFO sysinfo;
    GetSystemInfo(&sysinfo);
    return sysinfo.dwNumberOfProcessors;
#elif MACOS
    int nm[2];
    size_t len = 4;
    uint32_t count;

    nm[0] = CTL_HW; nm[1] = HW_AVAILCPU;
    sysctl(nm, 2, &count, &len, NULL, 0);

    if(count < 1) {
        nm[1] = HW_NCPU;
        sysctl(nm, 2, &count, &len, NULL, 0);
        if(count < 1) { count = 1; }
    }
    return count;
#else
    return sysconf(_SC_NPROCESSORS_ONLN);
#endif
}

回答by JesperE

On Linux, you can read the /proc/cpuinfo file and count the cores.

在 Linux 上,您可以读取 /proc/cpuinfo 文件并计算内核数。

回答by jakobengblom2

Note that "number of cores" might not be a particularly useful number, you might have to qualify it a bit more. How do you want to count multi-threaded CPUs such as Intel HT, IBM Power5 and Power6, and most famously, Sun's Niagara/UltraSparc T1 and T2? Or even more interesting, the MIPS 1004k with its two levels of hardware threading (supervisor AND user-level)... Not to mention what happens when you move into hypervisor-supported systems where the hardware might have tens of CPUs but your particular OS only sees a few.

请注意,“核心数”可能不是一个特别有用的数字,您可能需要对其进行更多限定。您想如何计算多线程 CPU,例如 Intel HT、IBM Power5 和 Power6,以及最著名的 Sun 的 Niagara/UltraSparc T1 和 T2?或者更有趣的是,MIPS 1004k 具有两个级别的硬件线程(管理程序和用户级别)......更不用说当您进入支持管理程序的系统时会发生什么,其中硬件可能有数十个 CPU 但您的特定操作系统只看到几个。

The best you can hope for is to tell the number of logical processing units that you have in your local OS partition. Forget about seeing the true machine unless you are a hypervisor. The only exception to this rule today is in x86 land, but the end of non-virtual machines is coming fast...

您所能希望的最好结果是告诉您本地操作系统分区中的逻辑处理单元的数量。除非您是管理程序,否则请忘记看到真正的机器。今天这条规则的唯一例外是在 x86 领域,但非虚拟机的末日即将到来......

回答by Ken

You probably won't be able to get it in a platform independent way. Windows you get number of processors.

您可能无法以独立于平台的方式获得它。Windows 你得到处理器的数量。

Win32 System Information

Win32 系统信息

回答by Constantin

One more Windows recipe: use system-wide environment variable NUMBER_OF_PROCESSORS:

另一个 Windows 秘诀:使用系统范围的环境变量NUMBER_OF_PROCESSORS

printf("%d\n", atoi(getenv("NUMBER_OF_PROCESSORS")));

回答by Matthias

Windows (x64 and Win32) and C++11

Windows(x64 和 Win32)和 C++11

The number of groups of logical processors sharing a single processor core.(Using GetLogicalProcessorInformationEx, see GetLogicalProcessorInformationas well)

共享单个处理器内核的逻辑处理器组的数量。(使用GetLogicalProcessorInformationEx,请参阅GetLogicalProcessorInformation以及)

size_t NumberOfPhysicalCores() noexcept {

    DWORD length = 0;
    const BOOL result_first = GetLogicalProcessorInformationEx(RelationProcessorCore, nullptr, &length);
    assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER);

    std::unique_ptr< uint8_t[] > buffer(new uint8_t[length]);
    const PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX info = 
            reinterpret_cast< PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX >(buffer.get());

    const BOOL result_second = GetLogicalProcessorInformationEx(RelationProcessorCore, info, &length);
    assert(result_second != FALSE);

    size_t nb_physical_cores = 0;
    size_t offset = 0;
    do {
        const PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX current_info =
            reinterpret_cast< PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX >(buffer.get() + offset);
        offset += current_info->Size;
        ++nb_physical_cores;
    } while (offset < length);

    return nb_physical_cores;
}

Note that the implementation of NumberOfPhysicalCoresis IMHO far from trivial (i.e. "use GetLogicalProcessorInformationor GetLogicalProcessorInformationEx"). Instead it is rather subtle if one reads the documentation (explicitly present for GetLogicalProcessorInformationand implicitly present for GetLogicalProcessorInformationEx) at MSDN.

请注意,NumberOfPhysicalCores恕我直言,实现远非微不足道(即“使用GetLogicalProcessorInformationGetLogicalProcessorInformationEx”)。相反,如果您阅读MSDN 上的文档(显式存在于GetLogicalProcessorInformation和隐式存在于GetLogicalProcessorInformationEx),则它是相当微妙的。

The number of logical processors.(Using GetSystemInfo)

逻辑处理器的数量。(使用GetSystemInfo

size_t NumberOfSystemCores() noexcept {
    SYSTEM_INFO system_info;
    ZeroMemory(&system_info, sizeof(system_info));

    GetSystemInfo(&system_info);

    return static_cast< size_t >(system_info.dwNumberOfProcessors);
}

Note that both methods can easily be converted to C/C++98/C++03.

请注意,这两种方法都可以轻松转换为 C/C++98/C++03。