以编程方式查找一台机器上的内核数量

有没有一种方法可以确定一台机器在C / C ++中具有多less核心? 如果不存在这样的事情,那么每个平台(Windows / * nix / Mac)的确定呢?

C ++ 11

//may return 0 when not able to detect unsigned concurentThreadsSupported = std::thread::hardware_concurrency(); 

参考: std :: thread :: hardware_concurrency


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

  • Win32的

     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; } 
  • HPUX

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

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

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

这个function是C ++ 11标准的一部分。

 #include <thread> unsigned int nthreads = std::thread::hardware_concurrency(); 

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

 #include <boost/thread.hpp> unsigned int nthreads = boost::thread::hardware_concurrency(); 

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

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

 int omp_get_num_procs(); 

函数返callback用时可用的处理器/内核的数量。

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

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

 #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 } 

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

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

你所希望的最好的就是告诉在你的本地操作系统分区中有多less个逻辑处理单元。 忘了看看真正的机器,除非你是一个pipe理程序。 这个规则今天唯一的例外是在x86的土地,但非虚拟机的末日来临… …

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

Win32系统信息

多一个Windows配方:使用系统范围的环境variablesNUMBER_OF_PROCESSORS

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

Windows Server 2003和更高版本可让您利用GetLogicalProcessorInformation函数

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

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

 grep processor /proc/cpuinfo | wc -l 

方便的脚本语言,如bash / perl / python / ruby​​。

hwloc(http://www.open-mpi.org/projects/hwloc/)值得一看。; 虽然需要将另一个库集成到代码中,但它可以提供有关处理器的所有信息(内核数量,拓扑结构等)

有关OS X的更多信息: sysconf(_SC_NPROCESSORS_ONLN)仅适用于版本> = 10.5,而不是10.4。

另一种方法是可用于版本> = 10.2的HW_AVAILCPU/sysctl() BSD代码。

在Linux上,我所知道的最好的编程方式就是使用

 sysconf(_SC_NPROCESSORS_CONF) 

要么

 sysconf(_SC_NPROCESSORS_ONLN) 

这些不是标准的,但在我的Linux手册页。

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

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

 grep -c ^processor /proc/cpuinfo 

要么

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

OS Xselect:根据文档,基于[[NSProcessInfo processInfo] processorCount]前面所述的解决scheme仅在OS X 10.5.0上可用。 对于早期版本的OS X,使用Carbon函数MPProcessors()。

如果你是一个Cocoa程序员,不要被这个是Carbon的事实吓倒。 您只需要将Carbon框架添加到您的Xcode项目中,并且MPProcessors()将可用。

对于Win32:

GetSystemInfo()获取逻辑处理器的数量,使用GetLogicalProcessorInformationEx()获取物理处理器的数量。

Windows(x64和Win32)和C ++ 11

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

 size_t NumberOfPhysicalCores() noexcept { DWORD length = 0; const BOOL result_first = GetLogicalProcessorInformationEx(RelationProcessorCore, nullptr, &length); Assert(result_first == FALSE); 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 == TRUE); 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的实现是恕我直言的(即“使用GetLogicalProcessorInformationGetLogicalProcessorInformationEx ”)。 相反,如果在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。

你也可以在.net中使用WMI,但是你依赖于wmi服务的运行等。有时它在本地工作,但是当在服务器上运行相同的代码时失败。 我认为这是一个命名空间问题,与您正在阅读的“名称”相关。

在Linux中,您可以检出dmesg并过滤ACPI初始化CPU的行,如下所示:

dmesg | grep 'ACPI: Processor dmesg | grep 'ACPI: Processor '

其他可能性是使用dmidecode来过滤处理器信息。