16

I am writing a small C application that use some threads for processing data. I want to be able to know the number of processors on a certain machine, without using system() & in combination to a small script.

The only way i can think of is to parse /proc/cpuinfo. Any other useful suggestions ?

Andrei Ciobanu
  • 12,500
  • 24
  • 85
  • 118
  • 6
    Almost a strict subset of this question: http://stackoverflow.com/questions/150355/programmatically-find-the-number-of-cores-on-a-machine (top answer has a linux one-liner). That question actually says C++, but the answer is C too. – Steve Jessop Apr 22 '10 at 19:53
  • Indeed, thanks for your feedback Steve, but what is considered the most portable approach in the "POSIX World", if I can call it this way? – Andrei Ciobanu Apr 22 '10 at 19:57
  • 3
    Not sure. Linux supports _SC_NPROCESSORS_ONLN, but it's not mandated by POSIX. Assuming that other answer is good, the fact that it uses a completely different and non-POSIX mechanism on BSD suggests that there isn't a simple POSIX-portable answer. Also, I found a warning online that _SC_NPROCESSORS_ONLN returns 1 instead of -1 for "I don't know", which is is not good if it's still true. – Steve Jessop Apr 22 '10 at 20:03
  • 2
    The way glibc implements `sysconf( _SC_NPROCESSORS_ONLN )` is by first trying /proc/stat . If it's there, it counts lines matching `/^cpu[0-9]/` . Otherwise, it looks at `/proc/cpuinfo` , whose format varies among architectures. – Joey Adams Apr 22 '10 at 20:06
  • Possible duplicate of [How to get the number of CPUs in Linux using C?](https://stackoverflow.com/questions/4586405/how-to-get-the-number-of-cpus-in-linux-using-c) – Ciro Santilli OurBigBook.com May 01 '18 at 13:10

6 Answers6

14

As others have mentioned in comments, this answer is useful:

numCPU = sysconf( _SC_NPROCESSORS_ONLN );

Leaving as a solution for folks that might skip over comments...

Community
  • 1
  • 1
mgalgs
  • 15,671
  • 11
  • 61
  • 74
  • 1
    Good solution, but seems like a Linux extension to POSIX: http://pubs.opengroup.org/onlinepubs/9699919799/functions/sysconf.html – Ciro Santilli OurBigBook.com Nov 03 '15 at 23:25
  • That solution is annoying because it is constant HW configuration but still compiling with optimization flags doesn't reduces the sysconf call in the assembler code. (gcc 4.4.6 on Red Hat, intel CPU) – Aviv Mar 22 '18 at 08:41
  • 2
    @Aviv The number of CPUs isn't constant hardware. They are hot-pluggable. – Zan Lynx Apr 12 '18 at 02:44
  • you are right, it occured to me later that I was wrong.but forgot about this comment. thanks – Aviv Apr 12 '18 at 05:35
8

Why not use sys/sysinfo.h?

#include <sys/sysinfo.h>
#include <stdio.h>
void main () {
   printf ("You have %d processors.\n", get_nprocs ());
}

Way more information can be found on the man page

$ man 3 get_nprocs
user2445797
  • 104
  • 1
  • 2
  • 2
    "These functions are GNU extensions" according to that man page. The question was about C/Linux in general (which does not always use glibc), and ideally POSIX. – Jesin Apr 01 '16 at 17:17
4
machine:/sys/devices/system/cpu$ ls
cpu0  cpu3  cpu6     kernel_max  perf_counters  sched_mc_power_savings
cpu1  cpu4  cpu7     offline     possible
cpu2  cpu5  cpuidle  online      present

If you have a machine with sysfs, take a look in /sys/devices/system/cpu.

Make sure you're asking for what you want -- CPUs, cores, hyperthreads, etc.

WhirlWind
  • 13,974
  • 3
  • 42
  • 42
4

The following was the code that I used to figure number of cores.....it might help you

//Finding the number of cores(logical processor) using cpuid instruction.....
    __asm
    {
        mov eax,01h //01h is for getting number of cores present in the processor
        cpuid
        mov t,ebx
    }

(t>>16)&0xff contains the number cores........

I guess this could help you http://lists.gnu.org/archive/html/autoconf/2002-08/msg00126.html

Vineel Kumar Reddy
  • 4,588
  • 9
  • 33
  • 37
  • 1
    That's not portable and does not compile with gcc. – fuz Apr 05 '16 at 06:27
  • 2
    The information returned by this is potentially wrong. If it is a NUMA machine (high end desktop or server with more than one CPU package), you will only get the number of cores in one CPU package. – doug65536 Aug 02 '20 at 22:35
0
#include <stdio.h>

void getPSN(char *PSN)
{int varEAX, varEBX, varECX, varEDX;
   char str[9];
   //%eax=1 gives most significant 32 bits in eax 
   __asm__ __volatile__ ("cpuid": "=a" (varEAX), "=b" (varEBX), "=c" (varECX), "=d" (varEDX) : "a" (1));
   sprintf(str, "%08X", varEAX); //i.e. XXXX-XXXX-xxxx-xxxx-xxxx-xxxx
   sprintf(PSN, "%C%C%C%C-%C%C%C%C", str[0], str[1], str[2], str[3], str[4], str[5], str[6], str[7]);
   //%eax=3 gives least significant 64 bits in edx and ecx [if PN is enabled]
   __asm__ __volatile__ ("cpuid": "=a" (varEAX), "=b" (varEBX), "=c" (varECX), "=d" (varEDX) : "a" (3));
   sprintf(str, "%08X", varEDX); //i.e. xxxx-xxxx-XXXX-XXXX-xxxx-xxxx
   sprintf(PSN, "%s-%C%C%C%C-%C%C%C%C", PSN, str[0], str[1], str[2], str[3], str[4], str[5], str[6], str[7]);
   sprintf(str, "%08X", varECX); //i.e. xxxx-xxxx-xxxx-xxxx-XXXX-XXXX
   sprintf(PSN, "%s-%C%C%C%C-%C%C%C%C", PSN, str[0], str[1], str[2], str[3], str[4], str[5], str[6], str[7]);
}

int main()
{
    char PSN[30]; //24 Hex digits, 5 '-' separators, and a '\0'
    getPSN(PSN);
    printf("%s\n", PSN); //compare with: lshw | grep serial:
    return 0;
}
Nitinkumar Ambekar
  • 969
  • 20
  • 39
0

Here's a minimal example of how to get physical cores and virtual threads:

#include <stdio.h>

...

unsigned int thread_count, core_count;
FILE *cpu_info = fopen("/proc/cpuinfo", "r");
while (!fscanf(cpu_info, "siblings\t: %u", &thread_count))
  fscanf(cpu_info, "%*[^s]");
while (!fscanf(cpu_info, "cpu cores\t: %u", &core_count))                   
  fscanf(cpu_info, "%*[^c]");                                                                                          
fclose(cpu_info);

It's more portable than _SC_NPROCESSORS_ONLN as it doesn't require glibc extensions.

Note that you don't need to check for EOF in this example as fscanf will return EOF if reached. This will cause the loop to stop safely.

Also, this example doesn't contain error checking to see if fopen failed. This should be done however you see fit.

This fscanf technique was derived from here: https://stackoverflow.com/a/43483850