tags:

views:

10104

answers:

15

This is more of a curiosity question than something that needs actual solving, but is there a way to determine how many cores a machine has from C++ in a platform-independent way? If no such thing exists, what about determining it per-platform (Windows/*nix/Mac)?

+1  A: 

Windows Server 2003 and later lets you leverage the GetLogicalProcessorInformation function

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

Chris Ballance
+10  A: 

On Linux, you can read the /proc/cpuinfo file and count the cores.

JesperE
Except that that also counts hyperthreaded or other SMT solutions as more cores...
jakobengblom2
jakobengblom2: And how is that /wrong/?
Arafangion
@Arafangion: hyperthreading is not true parallel execution, it's a technology for reducing context switching overhead. A hyperthreaded cpu can only *execute* one thread at a time, but it can store the architectural state (register values etc.) of two threads at the same time. The performance characteristics are very different from having two cores.
Wim Coenen
+5  A: 

You probably won't be able to get it in a platform independent way. Windows you get get number of processors.

Win32 System Information

Ken
Carefull: Hyperthreaded processors say there are two. So you also need to see if the processor are hyperthread capable.
Martin York
+20  A: 

The Boost.Thread library has a function called thread::hardware_concurrency() which returns the number of hardware threads available on a system based on number of cpus, cores or hyperthreading units.

Ferruccio
Appreciate you mentioning this, nice to know this functionality is in Boost now.
ceretullis
Seconded...was going to use the sample code above and some preprocessor macros to expose a single function, but the hard-work was done for me.
jkp
For win32, it's a call to GetSystemInfo. (As of boost Version 1.41.0) Does that capture all the info to determine how many worker threads would be effective? Does one need to consider both the number of cores and hyper-threading? unsigned thread::hardware_concurrency() { SYSTEM_INFO info={0}; GetSystemInfo( return info.dwNumberOfProcessors; }
Jive Dadson
According to MSDN, GetSystemInfo() returns the number of "physical processors" in dwNumberOfProcessors but it doesn't define what it means by that. The Boost documentation seems to claim that it includes hyperthreading units.
Ferruccio
see http://stackoverflow.com/questions/642348/does-getsysteminfo-give-you-the-total-number-of-virtual-cpus-i-e-hyper-threaded for hyperthreading
naugtur
A: 

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.

Evan Teran
+5  A: 

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. If you need some example code for it, just ask. :-)

Head Geek
Seriously, why did this get downrated?
DrJokepu
Great answer, thanks. ++
ttvd
+130  A: 

Win32:

SYSTEM_INFO sysinfo;
GetSystemInfo( &sysinfo );

numCPU = sysinfo.dwNumberOfProcessors;

Linux, Solaris, & AIX (per comments):

 numCPU = sysconf( _SC_NPROCESSORS_ONLN );

FreeBSD, macosx, NetBSD, OpenBSD, etc.:

nt mib[4];
size_t len; 

/* 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:

numCPU = mpctl(MPC_GETNUMSPUS, NULL, NULL);

IRIX:

numCPU = sysconf( _SC_NPROC_ONLN );


Mac OS X using Objective-C++:

NSUInteger a = [[NSProcessInfo processInfo] processorCount];
NSUInteger b = [[NSProcessInfo processInfo] activeProcessorCount];
ceretullis
Nice. Thorough. Awesome.
Tanktalus
I'd give you a double rate-up if I could.
Fhoxh
Thanks, I like to see thorough answers and code myself ;)
ceretullis
Fred Larson
Very nice answer. upvote for that :)
Johannes Schaub - litb
Environment.ProcessorCount?
Dmitri Nesteruk
@Dmitri Nesteruk: Environment.ProcessorCount is a .NET function, this question is tagged C++. Cheers.
ceretullis
Impressive! Great job!
Seth Illgard
Answers like this are the reason SO is so great!
sum1stolemyname
Add preprocessor directives so that only the OS-specific code is executed.
mcandre
@mcandre: that is left as an exercise for the reader. If I were implementing I'd probably use template-policy approach where the policy was defined in preprocessor directives. Or... you could use boost thread::hardware_concurrency().
ceretullis
+4  A: 

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 multithreaded 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 is to tell the number of logical processing units that you have in your local OS partition, you can really 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...

jakobengblom2
+13  A: 

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.

macbirdie
why did this get voted down, it's a reasonable answer
Evan Teran
+2  A: 

One more Windows recipe: use system-wide environment variable NUMBER_OF_PROCESSORS:

printf("%d\n", atoi(getenv("NUMBER_OF_PROCESSORS")));
Constantin
+1  A: 

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.

A: 

In Linux, you can checkout dmesg and filter the lines where ACPI initializes the CPUs, something like:

dmesg | grep 'ACPI: Processor'

Other possibility is to use dmidecode to filter out the processor information.

Hernán
A: 

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.

gauss256
A: 

Assembly code for this can be found in this question.

Nathan Fellman
+2  A: 

(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
}
Dirk-Jan Kroon