以编程方式查找机器上的核心数
有没有办法以与平台无关的方式从 C/C++ 确定机器有多少个核心? 如果不存在这样的东西,那么如何根据平台(Windows/*nix/Mac)确定它呢?
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)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(21)
C++11
参考:std::thread::hardware_concurrency
在 C++ 中在 C++11 之前,没有可移植的方法。 相反,您需要使用以下一种或多种方法(由适当的
#ifdef
行保护):Win32
Linux、Solaris、AIX 和 Mac OS X >=10.4(即 Tiger 及以上版本)
FreeBSD、MacOS X、NetBSD、OpenBSD 等
HPUX
IRIX
Objective-C(Mac OS X >=10.5 或 iOS)
C++11
Reference: 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
#ifdef
lines):Win32
Linux, Solaris, AIX and Mac OS X >=10.4 (i.e. Tiger onwards)
FreeBSD, MacOS X, NetBSD, OpenBSD, etc.
HPUX
IRIX
Objective-C (Mac OS X >=10.5 or iOS)
(几乎)C 代码中的平台独立函数
(Almost) Platform Independent function in c-code
此功能是 C++11 标准的一部分。
对于较旧的编译器,您可以使用 Boost.Thread图书馆。
无论哪种情况,
hardware_concurrency()
都会根据 CPU 核心和超线程单元的数量返回硬件能够同时执行的线程数。This functionality is part of the C++11 standard.
For older compilers, you can use the Boost.Thread library.
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.许多平台(包括 Visual Studio 2005)都支持 OpenMP,并且它提供了一个
返回可用处理器/内核数量的函数在通话时。
OpenMP is supported on many platforms (including Visual Studio 2005) and it offers a
function that returns the number of processors/cores available at the time of call.
如果您具有汇编语言访问权限,则可以使用 CPUID 指令来获取有关 CPU 的各种信息。 它可以在操作系统之间移植,但您需要使用制造商特定的信息来确定如何查找内核数量。 这是一个文档,描述了如何在 Intel 芯片上执行此操作,此的第 11 页描述了AMD 规范。
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 one describes the AMD specification.
在 Linux 上,您可以读取 /proc/cpuinfo 文件并计算内核数。
On Linux, you can read the /proc/cpuinfo file and count the cores.
Windows(x64 和 Win32)和 C++17
共享单个处理器核心的逻辑处理器组的数量。(使用 GetLogicalProcessorInformationEx,请参阅 GetLogicalProcessorInformation 以及)
请注意
NumberOfPhysicalCores
的实现恕我直言,这远非微不足道(即“使用GetLogicalProcessorInformation
或GetLogicalProcessorInformationEx
”)。 相反,如果阅读 MSDN 上的文档(显式显示GetLogicalProcessorInformation
和隐式显示GetLogicalProcessorInformationEx
),就会发现这一点相当微妙。逻辑处理器的数量.(使用 GetSystemInfo)
请注意,这两种方法都可以轻松转换为 C/C++98/C++03/C++11/C++14。
Windows (x64 and Win32) and C++17
The number of groups of logical processors sharing a single processor core. (Using GetLogicalProcessorInformationEx, see GetLogicalProcessorInformation as well)
Note that the implementation of
NumberOfPhysicalCores
is IMHO far from trivial (i.e. "useGetLogicalProcessorInformation
orGetLogicalProcessorInformationEx
"). Instead it is rather subtle if one reads the documentation (explicitly present forGetLogicalProcessorInformation
and implicitly present forGetLogicalProcessorInformationEx
) at MSDN.The number of logical processors. (Using GetSystemInfo)
Note that both methods can easily be converted to C/C++98/C++03/C++11/C++14.
另一种 Windows 秘诀:使用系统范围的环境变量
NUMBER_OF_PROCESSORS
:One more Windows recipe: use system-wide environment variable
NUMBER_OF_PROCESSORS
:请注意,“核心数”可能不是一个特别有用的数字,您可能需要对其进行更多限定。 您想如何计算多线程 CPU,例如 Intel HT、IBM Power5 和 Power6,以及最著名的 Sun 的 Niagara/UltraSparc T1 和 T2? 或者更有趣的是,MIPS 1004k 具有两级硬件线程(管理程序级和用户级)...更不用说当您进入虚拟机管理程序支持的系统时会发生什么,其中硬件可能有数十个 CPU,但您的特定操作系统只看到几个。
您所能期望的最好结果就是告诉您本地操作系统分区中拥有的逻辑处理单元的数量。 除非您是虚拟机管理程序,否则忘记看到真实的机器。 今天这条规则的唯一例外是在 x86 领域,但非虚拟机的终结即将到来......
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.
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...
您可能无法以独立于平台的方式获得它。 Windows 你可以获得处理器的数量。
Win32 系统信息
You probably won't be able to get it in a platform independent way. Windows you get number of processors.
Win32 System Information
有关 OS X 的更多信息:
sysconf(_SC_NPROCESSORS_ONLN)
仅适用于 >= 10.5 的版本,不适用于 10.4。另一种选择是
HW_AVAILCPU/sysctl()
BSD 代码,该代码在版本 >= 10.2 上可用。More on OS X:
sysconf(_SC_NPROCESSORS_ONLN)
is available only versions >= 10.5, not 10.4.An alternative is the
HW_AVAILCPU/sysctl()
BSD code which is available on versions >= 10.2.与 C++ 无关,但在 Linux 上我通常这样做:
对于 bash/perl/python/ruby 等脚本语言很方便。
Unrelated to C++, but on Linux I usually do:
Handy for scripting languages like bash/perl/python/ruby.
Windows Server 2003 及更高版本允许您利用 GetLogicalProcessorInformation 函数
http://msdn.microsoft .com/en-us/library/ms683194.aspx
Windows Server 2003 and later lets you leverage the GetLogicalProcessorInformation function
http://msdn.microsoft.com/en-us/library/ms683194.aspx
在 Linux 上,使用
_SC_NPROCESSORS_ONLN
可能不安全,因为它不是 POSIX 标准和 sysconf 手册中也有说明。 因此,_SC_NPROCESSORS_ONLN
可能不存在:一种简单的方法是读取
/proc/stat
或/proc/cpuinfo
并进行计数他们:使用
/proc/cpuinfo
:在 shell 中使用 grep 的方法相同:
或者
On Linux, it's may not be safe to to use
_SC_NPROCESSORS_ONLN
as it's not part of POSIX standard and the sysconf manual states as much. So there's a possibility that_SC_NPROCESSORS_ONLN
may not be present:A simple approach would be to read
/proc/stat
or/proc/cpuinfo
and count them:Using
/proc/cpuinfo
:The same approach in shell using grep:
Or
hwloc (http://www.open-mpi.org/projects/hwloc/) 值得一看。 虽然需要将另一个库集成到您的代码中,但它可以提供有关处理器的所有信息(核心数量、拓扑结构等)
hwloc (http://www.open-mpi.org/projects/hwloc/) is worth looking at. Though requires another library integration into your code but it can provide all the information about your processor (number of cores, the topology, etc.)
据我所知,在 Linux 上最好的编程方式是使用
或
这些不是标准的,但在我的 Linux 手册页中。
On linux the best programmatic way as far as I know is to use
or
These aren't standard, but are in my man page for Linux.
对于 Win32:
当 GetSystemInfo() 获取逻辑处理器的数量时,请使用
GetLogicalProcessorInformationEx()
获取物理处理器的数量。
For Win32:
While GetSystemInfo() gets you the number of logical processors, use
GetLogicalProcessorInformationEx()
to get the number of physical processors.
OS X 替代方案:根据文档,前面描述的基于 [[NSProcessInfo processInfo] handlerCount] 的解决方案仅在 OS X 10.5.0 上可用。 对于早期版本的 OS X,请使用 Carbon 函数 MPProcessors()。
如果您是一名 Cocoa 程序员,请不要因为这是 Carbon 而感到害怕。 您只需要将 Carbon 框架添加到您的 Xcode 项目中,MPProcessors() 就可用了。
OS X alternative: The solution described earlier based on [[NSProcessInfo processInfo] processorCount] is only available on OS X 10.5.0, according to the docs. For earlier versions of OS X, use the Carbon function MPProcessors().
If you're a Cocoa programmer, don't be freaked out by the fact that this is Carbon. You just need to need to add the Carbon framework to your Xcode project and MPProcessors() will be available.
也适用于 Linux:
Also works on Linux:
这应该返回系统上物理核心的数量。 这与大多数答案提供的逻辑核心数量不同。 如果您希望调整不执行阻塞 I/O 且不休眠的线程池的大小,那么您需要使用物理核心的数量,而不是逻辑(超线程)核心的数量。
该答案仅提供 Linux 和 BSD 的实现。
This should return the number of physical cores on the system. This is different than the number of logical cores which most of these answers provide. If you're looking to size a thread pool which performs no blocking I/O, and doesn't sleep, then you want to use the number of physical cores, not the number of logical (hyper threading) cores.
This answer only provides implementations for Linux and the BSDs.
你也可以在.net中使用WMI,但是你依赖于运行的wmi服务
有时它可以在本地运行,但当相同的代码在服务器上运行时就会失败。
我认为这是一个命名空间问题,与您正在读取其值的“名称”有关。
you can use WMI in .net too but you're then dependent on the wmi service running
etc. Sometimes it works locally, but then fail when the same code is run on servers.
I believe that's a namespace issue, related to the "names" whose values you're reading.