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


当前回答

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

其他回答

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

Windows (x64和Win32)和c++ 11

共享单个处理器核心的逻辑处理器组的数目。(使用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;
}

注意,NumberOfPhysicalCores的实现在我看来远非简单(例如:"使用GetLogicalProcessorInformation或GetLogicalProcessorInformationEx")。相反,如果阅读MSDN的文档(显式地为GetLogicalProcessorInformation提供,隐式地为GetLogicalProcessorInformationEx提供),就会发现这是相当微妙的。

逻辑处理器的数量。(使用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);
}

注意,这两种方法都可以很容易地转换为C/ c++ 98/ c++ 03。

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

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

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

在Linux上,使用_SC_NPROCESSORS_ONLN可能是不安全的,因为它不是POSIX标准的一部分,sysconf手册也有同样的说明。所以有可能_SC_NPROCESSORS_ONLN不存在:

 These values also exist, but may not be standard.

     [...]     

     - _SC_NPROCESSORS_CONF
              The number of processors configured.   
     - _SC_NPROCESSORS_ONLN
              The number of processors currently online (available).

一个简单的方法是读取/proc/stat或/proc/cpuinfo并计算它们:

#include<unistd.h>
#include<stdio.h>

int main(void)
{
char str[256];
int procCount = -1; // to offset for the first entry
FILE *fp;

if( (fp = fopen("/proc/stat", "r")) )
{
  while(fgets(str, sizeof str, fp))
  if( !memcmp(str, "cpu", 3) ) procCount++;
}

if ( procCount == -1) 
{ 
printf("Unable to get proc count. Defaulting to 2");
procCount=2;
}

printf("Proc Count:%d\n", procCount);
return 0;
}

使用 /proc/cpuinfo:

#include<unistd.h>
#include<stdio.h>

int main(void)
{
char str[256];
int procCount = 0;
FILE *fp;

if( (fp = fopen("/proc/cpuinfo", "r")) )
{
  while(fgets(str, sizeof str, fp))
  if( !memcmp(str, "processor", 9) ) procCount++;
}

if ( !procCount ) 
{ 
printf("Unable to get proc count. Defaulting to 2");
procCount=2;
}

printf("Proc Count:%d\n", procCount);
return 0;
}

同样的方法在shell中使用grep:

grep -c ^processor /proc/cpuinfo

Or

grep -c ^cpu /proc/stat # subtract 1 from the result