How to get the number of CPUs in Linux using C?

75,476

Solution 1

#include <stdio.h>
#include <sys/sysinfo.h>

int main(int argc, char *argv[])
{
    printf("This system has %d processors configured and "
        "%d processors available.\n",
        get_nprocs_conf(), get_nprocs());
    return 0;
}

https://linux.die.net/man/3/get_nprocs

Solution 2

#include <unistd.h>
long number_of_processors = sysconf(_SC_NPROCESSORS_ONLN);

Solution 3

This code (drawn from here) should work on both windows and *NIX platforms.

#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#include <unistd.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>


int main() {
  long nprocs = -1;
  long nprocs_max = -1;
#ifdef _WIN32
#ifndef _SC_NPROCESSORS_ONLN
SYSTEM_INFO info;
GetSystemInfo(&info);
#define sysconf(a) info.dwNumberOfProcessors
#define _SC_NPROCESSORS_ONLN
#endif
#endif
#ifdef _SC_NPROCESSORS_ONLN
  nprocs = sysconf(_SC_NPROCESSORS_ONLN);
  if (nprocs < 1)
  {
    fprintf(stderr, "Could not determine number of CPUs online:\n%s\n", 
strerror (errno));
    exit (EXIT_FAILURE);
  }
  nprocs_max = sysconf(_SC_NPROCESSORS_CONF);
  if (nprocs_max < 1)
  {
    fprintf(stderr, "Could not determine number of CPUs configured:\n%s\n", 
strerror (errno));
    exit (EXIT_FAILURE);
  }
  printf ("%ld of %ld processors online\n",nprocs, nprocs_max);
  exit (EXIT_SUCCESS);
#else
  fprintf(stderr, "Could not determine number of CPUs");
  exit (EXIT_FAILURE);
#endif
}

Solution 4

sched_affinity() version you mention in the beginning is still better than /proc/cpuinfo and/or _SC_NPROCESSORS_ONLN since it only counts CPUs available for a given process (some may be disabled by sched_setaffinity() invoked by an outside process). The only change would be using CPU_COUNT() instead of doing CPU_ISSET in a loop.

Solution 5

Using /proc/cpuinfo is the cleanest and most portable solution. In case the open fails, you could simply assume 1 cpu or 2 cpus. Code that depends on knowing the number of cpus for a purpose other than micro-optimizing (e.g. choosing the ideal number of threads to run) is almost surely doing something dumb.

The _SC_NPROCESSORS_ONLN solution depends on a non-standard (glibc-specific) sysconf extension, which is a much bigger dependency than /proc (all Linux systems have /proc, but some have non-glibc libcs or older versions of glibc that lack _SC_NPROCESSORS_ONLN).

Share:
75,476
Treviño
Author by

Treviño

Updated on February 02, 2022

Comments

  • Treviño
    Treviño about 2 years

    Is there an API to get the number of CPUs available in Linux? I mean, without using /proc/cpuinfo or any other sys-node file...

    I've found this implementation using sched.h:

    int GetCPUCount()
    {
     cpu_set_t cs;
     CPU_ZERO(&cs);
     sched_getaffinity(0, sizeof(cs), &cs);
    
     int count = 0;
     for (int i = 0; i < 8; i++)
     {
      if (CPU_ISSET(i, &cs))
       count++;
     }
     return count;
    }
    

    But, isn't there anything more higher level using common libraries?

  • chrisaycock
    chrisaycock over 13 years
    +1 The OP seemed adamant about hanging himself, so I just gave him the rope.
  • R.. GitHub STOP HELPING ICE
    R.. GitHub STOP HELPING ICE over 13 years
    I think Ulrich Drepper gave him the rope. I really don't understand the motivation for adding non-standard things like this when there's an existing, much cleaner and much more portable way to do the same thing. (If you write _SC_NPROCESSORS_ONLN in your program, it will fail to compile if the constant is missing, but the other ways just fail at runtime (failed open, etc.) and any sane code would handle the failure condition.)
  • Vikram.exe
    Vikram.exe over 13 years
    I got this code a long time back from some one (don't remember the name).
  • MarkR
    MarkR over 13 years
    I'm not sure posting this code snippet really answers the OP's question, although they might reverse-engineer some useful info out of it.
  • MarkR
    MarkR over 13 years
    In what way is /proc/cpuinfo portable? This is a Linux-specific interface (some other systems emulate it, for example, FreeBSD with the linprocfs filesystem mounted in /proc). the sysconfig _SC_NPROCESSORS_ONLN for example, is supported by FreeBSD.
  • R.. GitHub STOP HELPING ICE
    R.. GitHub STOP HELPING ICE over 13 years
    It's portable in that it doesn't prevent your program from running on systems where it's not available, and on systems where /proc doesn't have a special meaning, a simple text file with the right information could be stored by the administrator in /proc/cpuinfo.
  • poindexter
    poindexter almost 12 years
    I agree with MarkR. chrisaycock provides a succinct answer.
  • ebasconp
    ebasconp almost 9 years
    Parsing a file in order to get low level information is completely primitive (and hard to maintain if the file format changes or vary across implementations).
  • cHao
    cHao over 8 years
    @oopscene: Getting, or IMO even caring about, low level information is primitive, by definition. Once you do care, though, getting it from text files allows for abstractions that syscalls and such simply can't match. Like the one mentioned in the comment right above yours.
  • Ciro Santilli OurBigBook.com
    Ciro Santilli OurBigBook.com over 8 years
    Good solution, but seems like a Linux extension to POSIX: pubs.opengroup.org/onlinepubs/9699919799/functions/sysconf.h‌​tml
  • iDebD_gh
    iDebD_gh over 7 years
    This gives number of cores online. If I make any core offline, it will not returned here
  • Damon
    Damon over 7 years
    @cHao: This is untrue. Caring about the number of CPUs (and moreso, the number of hyperthreaded cores) is only "primitive" insofar as it is a basic piece of information that is needed for most non-trivial modern programs (yes, it is not 1980 any more). While other operating systems are arguably poor at getting this information programatically (e.g. 35 lines of code with a loop and several memory allocations under Windows) the LInux approach "parse a text file" is simply ridiculous. Even more so as they can't even agree on whether /proc or /sys is the correct thing.
  • cHao
    cHao over 7 years
    @Damon: It's "primitive" in that it relies directly on what hardware you're running. Firstly, no, you don't need that information in the vast majority of cases. While it can occasionally be used to optimize the number of waiting threads or whatever, a program that breaks because it doesn't know how many cores are available is already quite broken. But secondly, the Linux approach doesn't even require Linux. And i've yet to see a Linux machine where /proc/cpuinfo is unavailable.
  • Saurav Seth
    Saurav Seth over 5 years
    @iDebD_gh - If I'm not mistaken, that's what _SC_NPROCESSORS_CONF provides.
  • Guido Flohr
    Guido Flohr about 5 years
    You should use the #error preprocessor directive if _SC_NPROCESSORS_ONLN is not defined. This is a compile-time failure, not a run-time failure.
  • Alexis Wilke
    Alexis Wilke about 5 years
    In the first example, edx says 4 (I don't have hyperthreading turned on, but I don't get 1.) Is it possible that you made a small mistake here?
  • Alexis Wilke
    Alexis Wilke about 5 years
    I think that the only drawback here is that some of the CPUs may not be available to you for one reason or another. The CPUID instruction is likely to ignore that OS feature. That being said, I've yet to come across such a system!
  • Alexis Wilke
    Alexis Wilke about 5 years
    Also this is specific to Intel processors en.wikipedia.org/wiki/CPUID#EAX=4_and_EAX=Bh:_Intel_thread/…
  • Zibri
    Zibri over 4 years
    @AlexisWilke I stated that in the first line of my answer. Did you miss that or you love to state the obvious? ;)
  • mLstudent33
    mLstudent33 over 4 years
    what is the difference between threads, actual threads and hyperthreading in a nutshell in terms of allocating threads to cores for say a summation or matrix multiplication?
  • Lewis Chan
    Lewis Chan almost 4 years
    @iDebD_gh What do you mean by offline core ?
  • user1637056
    user1637056 over 3 years
    Would this still be correct if the process has called cpu_setaffinity to restrict the number of affine CPUs?
  • S.Goswami
    S.Goswami over 3 years
    For the test, I have a bash script while : ; do echo 0 > /sys/devices/system/cpu/cpu3/online && sleep 0.5 && echo 1 > /sys/devices/system/cpu/cpu3/online ; sleep 0.5 ; echo Hey! ; done ; it switches off and on cpu3 really fast. sysconf(_SC_NPROCESSORS_ONLN) fails to show the correct CPU when put inside a while loop, but if I put that in a watch -n 0.1 ./a.out (terrible choice), then it shows the core counts correctly. Same thing with getconf, it restarts every time in watch, and shows correct info. Your script also shows the correct values.
  • S.Goswami
    S.Goswami over 3 years
    But the caveat being if I use task -c 0 ./a.out, it gives me procs=1 instead of 4, in other words it just counts the CPU assigned to the process.
  • Ed Bennett
    Ed Bennett over 2 years
    This answer does not give the same result as the snippet given in the question. If a process is bound to a subset of the CPUs on the machine using taskset, then the method using sched_getaffinity() gives the number of allocated CPUs, while get_nprocs() gives the total number of CPUs that the machine has available. This is bad if you're using this to decide on a number of threads, since if only a single core is allocated on a many-core machine then the process will thrash.
  • ChrisZZ
    ChrisZZ about 2 years
    With the posted code in this answer running on my machine, I got 4 cores, 6 threads, hyperthread YES. But with the library cpuinfo installed and called from my cpp file, there is 6 cores and 6 processors. I don't understand why got different number of cores.