有没有一种方法可以以平台无关的方式确定一台机器有多少个C/ c++内核?如果不存在这样的东西,如何确定每个平台(Windows/*nix/Mac)?


当前回答

Windows Server 2003及以后版本允许您利用GetLogicalProcessorInformation函数

http://msdn.microsoft.com/en-us/library/ms683194.aspx

其他回答

#include <stdint.h>

#if defined(__APPLE__) || defined(__FreeBSD__)
#include <sys/sysctl.h>

uint32_t num_physical_cores(void)
{
    uint32_t num_cores      = 0;
    size_t num_cores_len    = sizeof(num_cores);

    sysctlbyname("hw.physicalcpu", &num_cores, &num_cores_len, 0, 0);

    return num_cores;
}
#elif defined(__linux__)
#include <unistd.h>
#include <stdio.h>
uint32_t num_physical_cores(void)
{
    uint32_t lcores = 0, tsibs = 0;

    char buff[32];
    char path[64];

    for (lcores = 0;;lcores++) {
        FILE *cpu;

        snprintf(path, sizeof(path), "/sys/devices/system/cpu/cpu%u/topology/thread_siblings_list", lcores);

        cpu = fopen(path, "r");
        if (!cpu) break;

        while (fscanf(cpu, "%[0-9]", buff)) {
            tsibs++;
            if (fgetc(cpu) != ',') break;
        }

        fclose(cpu);
    }

    return lcores / (tsibs / lcores);
}
#else
#error Unrecognized operating system
#endif

这将返回系统上的物理核数。这与大多数答案提供的逻辑核数量不同。如果您希望确定一个不执行阻塞I/O且不休眠的线程池的大小,那么您希望使用物理内核的数量,而不是逻辑(超线程)内核的数量。

这个答案只提供Linux和bsd的实现。

C++11

#include <thread>

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

参考:std::线程::hardware_concurrency


在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];

这个功能是c++ 11标准的一部分。

#include <thread>

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

对于较老的编译器,可以使用Boost。线程库。

#include <boost/thread.hpp>

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

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

与c++无关,但在Linux上我通常这样做:

grep processor /proc/cpuinfo | wc -l

适用于bash/perl/python/ruby等脚本语言。

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