How to get the number of CPUs in Linux using C?
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
).
Treviño
Updated on February 02, 2022Comments
-
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 over 13 years+1 The OP seemed adamant about hanging himself, so I just gave him the rope.
-
R.. GitHub STOP HELPING ICE over 13 yearsI 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 (failedopen
, etc.) and any sane code would handle the failure condition.) -
Vikram.exe over 13 yearsI got this code a long time back from some one (don't remember the name).
-
MarkR over 13 yearsI'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 over 13 yearsIn 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 over 13 yearsIt'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 almost 12 yearsI agree with MarkR. chrisaycock provides a succinct answer.
-
ebasconp almost 9 yearsParsing 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 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 over 8 yearsGood solution, but seems like a Linux extension to POSIX: pubs.opengroup.org/onlinepubs/9699919799/functions/sysconf.html
-
iDebD_gh over 7 yearsThis gives number of cores online. If I make any core offline, it will not returned here
-
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 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 over 5 years@iDebD_gh - If I'm not mistaken, that's what
_SC_NPROCESSORS_CONF
provides. -
Guido Flohr about 5 yearsYou 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 about 5 yearsIn 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 about 5 yearsI 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 about 5 yearsAlso this is specific to Intel processors en.wikipedia.org/wiki/CPUID#EAX=4_and_EAX=Bh:_Intel_thread/…
-
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 over 4 yearswhat 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 almost 4 years@iDebD_gh What do you mean by offline core ?
-
user1637056 over 3 yearsWould this still be correct if the process has called cpu_setaffinity to restrict the number of affine CPUs?
-
S.Goswami over 3 yearsFor 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 awatch -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 over 3 yearsBut the caveat being if I use
task -c 0 ./a.out
, it gives meprocs=1
instead of 4, in other words it just counts the CPU assigned to the process. -
Ed Bennett over 2 yearsThis 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 usingsched_getaffinity()
gives the number of allocated CPUs, whileget_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 about 2 yearsWith 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.