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)?
C++11
#include <thread>
//may return 0 when not able to detect
const auto processor_count = std::thread::hardware_concurrency();
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
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];
HW_NCPU
is deprecated on OS X. On Windows GetSystemInfo
is only useful if your system has 32 logical processors or less, use GetLogicalProcessorInformation
for systems that have more than 32 logical processors. –
Schaal std::thread::hardware_concurrency
implementations differ; Visual Studio takes into account affinity (returns 1 if process is restricted to one core etc.) whereas g++ does not. –
Azoth GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS)
to retrieve a complete count. See github.com/python/cpython/commit/… for an example. –
Flexed sysconf
, sysctl
, etc.) are defined? –
Steeve This functionality is part of the C++11 standard.
#include <thread>
unsigned int nthreads = std::thread::hardware_concurrency();
For older compilers, you can use the Boost.Thread library.
#include <boost/thread.hpp>
unsigned int nthreads = boost::thread::hardware_concurrency();
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.
OpenMP is supported on many platforms (including Visual Studio 2005) and it offers a
int omp_get_num_procs();
function that returns the number of processors/cores available at the time of call.
sched_setaffinity
this will not work. –
Venavenable 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.
(Almost) Platform Independent function in c-code
#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
}
HW_NCPU
is deprecated on OS X source –
Schaal On Linux, you can read the /proc/cpuinfo file and count the cores.
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...
One more Windows recipe: use system-wide environment variable NUMBER_OF_PROCESSORS
:
printf("%d\n", atoi(getenv("NUMBER_OF_PROCESSORS")));
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)
size_t NumberOfPhysicalCores() noexcept {
DWORD length = 0;
const BOOL result_first = GetLogicalProcessorInformationEx(RelationProcessorCore, nullptr, &length);
assert(GetLastError() == ERROR_INSUFFICIENT_BUFFER);
std::unique_ptr< std::byte[] > buffer(new std::byte[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;
}
Note that the implementation of NumberOfPhysicalCores
is IMHO far from trivial (i.e. "use GetLogicalProcessorInformation
or GetLogicalProcessorInformationEx
"). Instead it is rather subtle if one reads the documentation (explicitly present for GetLogicalProcessorInformation
and implicitly present for GetLogicalProcessorInformationEx
) at MSDN.
The number of logical processors. (Using 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);
}
Note that both methods can easily be converted to C/C++98/C++03/C++11/C++14.
size_t
casts. (Although, msvc++ does not complain at W4.) –
Neotropical __STDCPP_DEFAULT_NEW_ALIGNMENT__ >= alignof(std::max_align_t) >= alignof(_SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX)
(and any sane user-defined overload of operator new(std::size_t)
should use an alignment of at least __STDCPP_DEFAULT_NEW_ALIGNMENT__
) 2) Changed the type explicitly from std::uint8_t
to std::byte
which has relaxed aliasing rules (one would, however, have an odd Windows system if std::uint8_t
is not a type alias of unsigned char
, which has relaxed aliasing rules as well). –
Neotropical std::byte
and its ilk into the struct. The normal solution would be memcpy or std::bit_cast
. –
Rapping You probably won't be able to get it in a platform independent way. Windows you get number of processors.
Unrelated to C++, but on Linux I usually do:
grep processor /proc/cpuinfo | wc -l
Handy for scripting languages like bash/perl/python/ruby.
import multiprocessing
print multiprocessing.cpu_count()
–
Novation grep
has -c
flag to count entries! –
Oliveolivegreen model name : ARMv6-compatible processor rev 7 (v6l)
in its cpuinfo, so one probably out to use grep -c ^processor /proc/cpuinfo
–
Wotton psutil
is better than multiprocessing
since you can check for physcial cores only by passing logical=False
. –
Lavoisier 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.
Windows Server 2003 and later lets you leverage the GetLogicalProcessorInformation function
On linux the best programmatic way as far as I know is to use
sysconf(_SC_NPROCESSORS_CONF)
or
sysconf(_SC_NPROCESSORS_ONLN)
These aren't standard, but are in my man page for Linux.
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.)
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:
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).
A simple approach would be to read /proc/stat
or /proc/cpuinfo
and count them:
#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;
}
Using /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;
}
The same approach in shell using grep:
grep -c ^processor /proc/cpuinfo
Or
grep -c ^cpu /proc/stat # subtract 1 from the result
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.
For Win32:
While GetSystemInfo() gets you the number of logical processors, use GetLogicalProcessorInformationEx() to get the number of physical processors.
Also works on Linux:
#include<sys/sysinfo.h>
int nproc = get_nprocs();
int nproc_conf = get_nprocs_conf();
printf("processors available: %d, configured: %d\n", nproc, nproc_conf);
#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
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.
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.
© 2022 - 2024 — McMap. All rights reserved.
std::thread::hardware_concurrency
returns the number of physical CPU cores, butnproc
in Linux shows only the number of CPU cores the current process can run on, which can be controlled withsched_setaffinity
. I haven't found a way to get that instead from standard C++:, see e.g. in Python: stackoverflow.com/questions/1006289/… – Spradlin