以编程方式查找计算机上的内核数
有没有一种方法可以以平台无关的方式确定C / C ++中一台计算机有多少个内核?如果不存在这样的东西,那么如何根据平台确定它(Windows / * nix / Mac)?
解决方案
Windows Server 2003和更高版本允许我们利用GetLogicalProcessorInformation函数
http://msdn.microsoft.com/en-us/library/ms683194.aspx
在Linux上,我们可以读取/ proc / cpuinfo文件并计算内核数。
我们可能将无法以独立于平台的方式获得它。在Windows中,我们可以获得处理器数量。
Win32系统信息
此功能是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内核和超线程单元的数量返回硬件能够同时执行的线程数。
据我所知,在Linux上,最好的编程方式是使用
sysconf(_SC_NPROCESSORS_CONF)
或者
sysconf(_SC_NPROCESSORS_ONLN)
这些不是标准的,但是在我的Linux手册页中。
如果我们具有汇编语言访问权限,则可以使用CPUID指令来获取有关CPU的各种信息。尽管我们需要使用制造商特定的信息来确定如何找到内核数量,但是它可以在操作系统之间移植。这是描述如何在Intel芯片上执行此操作的文档,该文档的第11页介绍了AMD规范。
//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; }
- 惠普
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];
请注意,"核心数"可能不是一个特别有用的数字,我们可能需要对其进行更多限定。我们想如何计算多线程CPU,例如Intel HT,IBM Power5和Power6,以及最著名的Sun的Niagara / UltraSparc T1和T2?甚至更有趣的是,具有两个级别的硬件线程的MIPS 1004k(管理程序和用户级别)...更不用说当我们进入虚拟机管理程序支持的系统时,硬件可能有数十个CPU但特定操作系统只看到一些。
最好的希望是告诉我们本地OS分区中逻辑处理单元的数量。除非我们是虚拟机监控程序,否则不要再看真实的机器了。今天,此规则的唯一例外是在x86领域,但非虚拟机的终结日趋迅速。
许多平台(包括Visual Studio 2005)都支持OpenMP,并且它提供了
int omp_get_num_procs();
该函数返回调用时可用的处理器/内核数。
Windows的另一个秘诀:使用系统范围的环境变量NUMBER_OF_PROCESSORS
:
printf("%d\n", atoi(getenv("NUMBER_OF_PROCESSORS")));
我们也可以在.net中使用WMI,但是我们依赖于运行的WMI服务
等等。有时它在本地运行,但是当在服务器上运行相同的代码时失败。
我认为这是一个名称空间问题,与我们正在读取其值的"名称"有关。
在Linux中,我们可以检出dmesg并过滤ACPI初始化CPU的行,例如:
dmesg | grep'ACPI:Processor
'
其他可能性是使用dmidecode过滤掉处理器信息。
OS X替代品:根据文档,先前基于[[NSProcessInfo processInfo] processorCount]描述的解决方案仅在OS X 10.5.0上可用。对于OS X的早期版本,请使用Carbon函数MPProcessors()。
如果我们是Cocoa程序员,请不要因为这是Carbon而感到惊讶。我们只需要向Xcode项目中添加Carbon框架,即可使用MPProcessors()。
(几乎)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 }