Wie erhalte ich die Anzahl der CPUs in Linux mit C?

Lesezeit: 7 Minuten

Benutzeravatar von Treviño
Treviño

Gibt es eine API, um die Anzahl der in Linux verfügbaren CPUs abzurufen? Ich meine, ohne /proc/cpuinfo oder eine andere Sys-Node-Datei zu verwenden …

Ich habe diese Implementierung mit sched.h gefunden:

int GetCPUCount()
{
 cpu_set_t cs;
 CPU_ZERO(&cs);
 sched_getaffinity(0, sizeof(cs), &cs);

 int count = 0;
 for (int i = 0; i < 64; i++)
 {
  if (CPU_ISSET(i, &cs))
   count++;
  else
   break;
 }
 return count;
}

Aber gibt es nicht etwas Höheres, das gemeinsame Bibliotheken verwendet?

  • Warum haben die Leute solche Angst, /proc zu verwenden? Jede Linux-Box, die ich in den letzten 15 Jahren gesehen habe, hat es, es ist immer auf dem neuesten Stand mit dem, was der Kernel weiß, und das Format der darin vorhandenen Dinge ändert sich nicht viel.

    – chao

    3. Januar 2011 um 16:58 Uhr

  • Ich finde es toll, dass du versuchst, verschiedene Vorgehensweisen zu lernen, aber versuchst du, das Rad neu zu erfinden?

    – David Weiser

    3. Januar 2011 um 17:09 Uhr

  • Siehe auch stackoverflow.com/questions/150355/…

    – Jay Sullivan

    1. Februar 2020 um 15:53 ​​Uhr

  • /proc ist nicht portabel

    – Edd Barrett

    2. Juni 2021 um 11:07 Uhr

  • @cHao Weil /proc Cgroups ignoriert, was zu einer “Überbelegung” führen kann, wenn der Prozess mehr Threads ausführt, als ihm in der Cpuset-Cgroup gewährt werden.

    – phzx_munki

    14. Februar um 21:28 Uhr

Benutzeravatar von chrisaycock
chrisaycock

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

  • Gute Lösung, scheint aber eine Linux-Erweiterung zu POSIX zu sein: pubs.opengroup.org/onlinepubs/9699919799/functions/sysconf.html

    – Ciro Santilli OurBigBook.com

    3. November 2015 um 23:26 Uhr

  • Dies gibt die Anzahl der Kerne online an. Wenn ich einen Kern offline mache, wird er nicht hierher zurückgebracht

    – iDebD_gh

    8. September 2016 um 7:01 Uhr

  • @iDebD_gh – Wenn ich mich nicht irre, ist es das _SC_NPROCESSORS_CONF bietet.

    – selbe

    22. November 2018 um 3:20 Uhr

  • @iDebD_gh Was meinst du mit Offline-Kern?

    – Lewis Chan

    20. Mai 2020 um 9:05 Uhr

Benutzeravatar von Володимир Ніколайчук
Володимир Ніколайчук

#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

  • Diese Antwort liefert nicht das gleiche Ergebnis wie der in der Frage angegebene Ausschnitt. Wenn ein Prozess an eine Teilmenge der CPUs auf der Maschine gebunden ist, die verwendet wird tasksetdann die Methode mit sched_getaffinity() gibt die Anzahl der zugewiesenen CPUs an, während get_nprocs() gibt die Gesamtzahl der CPUs an, die der Maschine zur Verfügung stehen. Dies ist schlecht, wenn Sie dies verwenden, um sich für eine Reihe von Threads zu entscheiden, denn wenn nur ein einzelner Kern auf einer Maschine mit vielen Kernen zugewiesen wird, wird der Prozess ins Stocken geraten.

    – Ed Bennett

    1. September 2021 um 9:59 Uhr


Benutzeravatar von Vikram.exe
Vikram.exe

Dieser Code (gezeichnet aus hier) sollte sowohl auf Windows- als auch auf *NIX-Plattformen funktionieren.

#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
}

  • Ich habe diesen Code vor langer Zeit von jemandem bekommen (erinnere mich nicht an den Namen).

    – Vikram.exe

    3. Januar 2011 um 18:10 Uhr

  • Ich bin mir nicht sicher, ob das Posten dieses Code-Snippets die Frage des OP wirklich beantwortet, obwohl sie möglicherweise einige nützliche Informationen daraus zurückentwickeln.

    – MarkR

    4. Januar 2011 um 6:47 Uhr

  • Ich stimme MarkR zu. Chrisaycock gibt eine prägnante Antwort.

    – Zeiger

    5. Juli 2012 um 17:41 Uhr

  • Sie sollten die verwenden #error Präprozessordirektive if _SC_NPROCESSORS_ONLN ist nicht definiert. Dies ist ein Kompilierzeitfehler, kein Laufzeitfehler.

    – Guido Flohr

    3. Februar 2019 um 11:43 Uhr

Verwenden /proc/cpuinfo ist die sauberste und tragbarste Lösung. Falls das Öffnen fehlschlägt, können Sie einfach von 1 CPU oder 2 CPUs ausgehen. Code, der davon abhängt, die Anzahl der CPUs für einen anderen Zweck als die Mikrooptimierung zu kennen (z. B. die Auswahl der idealen Anzahl von auszuführenden Threads), macht mit ziemlicher Sicherheit etwas Dummes.

Das _SC_NPROCESSORS_ONLN Lösung hängt von einem Nicht-Standard ab (glibc-spezifisch) sysconf Erweiterung, die eine viel größere Abhängigkeit als ist /proc (Alle Linux-Systeme haben /procaber einige haben nicht-glibc-libcs ​​oder ältere glibc-Versionen, die fehlen _SC_NPROCESSORS_ONLN).

Benutzeravatar von RCL
RCL

sched_affinity() Version, die Sie am Anfang erwähnen, ist immer noch besser als /proc/cpuinfo und/oder _SC_NPROCESSORS_ONLN da es nur CPUs zählt, die für einen bestimmten Prozess verfügbar sind (einige können durch deaktiviert werden sched_setaffinity() von einem externen Prozess aufgerufen). Die einzige Änderung wäre die Verwendung CPU_COUNT() statt zu tun CPU_ISSET in einer Schleife.

Benutzeravatar von Peter Cordes
Peter Kordes

Persönlich für neuere Intel-CPUs (allgemein nicht x86, nur Intel) Ich benutze die EAX=0Bh cpuid Blatt. Sehen Wikipedia für einige Details darüber, welche Informationen Sie über die Kerne im aktuellen Socket-Aka-Paket erhalten. Auf einem Multi-Socket-System kann dies die Hälfte oder ein Viertel der systemweiten Anzahl physischer/logischer Kerne sein. Intel hat ein Whitepaper zum Aufzählen von CPUs mit Details darüber, was bei Multi-Socket-Systemen zu überprüfen ist. Dieser Code macht das nicht, er prüft nur ein Unterblatt (ECX=1).

int main()
{
unsigned int eax=11,ebx=0,ecx=1,edx=0;

asm volatile("cpuid"
        : "=a" (eax),
          "=b" (ebx),
          "=c" (ecx),
          "=d" (edx)
        : "0" (eax), "2" (ecx)
        : );
            
printf("Cores: %d\nThreads: %d\nActual thread: %d\n",eax,ebx,edx);
}

Ausgabe:

Cores: 4
Threads: 8
Actual thread: 1

Oder kürzer:

#include <stdio.h>

int main()
{
unsigned int ncores=0,nthreads=0,ht=0;

asm volatile("cpuid": "=a" (ncores), "=b" (nthreads) : "a" (0xb), "c" (0x1) : );

ht=(ncores!=nthreads);

printf("Cores: %d\nThreads: %d\nHyperThreading: %s\n",ncores,nthreads,ht?"Yes":"No");

return 0;
}

Ausgabe:

Cores: 4
Threads: 8
HyperThreading: Yes

Benutzeravatar von Damien Zammit
Damien Zamit

Keine der Antworten, die beinhalten sysconf(...) oder get_nprocs() sind korrekt, um die Anzahl der Prozessoren zu berücksichtigen, die durch die CPU-Affinität auf eine Aufgabe beschränkt sind.

Sie brauchen so etwas, um die Anzahl der für eine Aufgabe verfügbaren Prozessoren zu erhalten:

#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>

int nprocs()
{
  cpu_set_t cs;
  CPU_ZERO(&cs);
  sched_getaffinity(0, sizeof(cs), &cs);
  return CPU_COUNT(&cs);
}

int main()
{
  printf("procs=%d\n", nprocs());
  return 0;
}

  • Wäre dies immer noch richtig, wenn der Prozess cpu_setaffinity aufgerufen hat, um die Anzahl der affinen CPUs zu beschränken?

    – Benutzer1637056

    10. August 2020 um 23:43 Uhr

  • Für den Test habe ich ein Bash-Skript 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 ; es schaltet CPU3 sehr schnell aus und ein. sysconf(_SC_NPROCESSORS_ONLN) zeigt nicht die richtige CPU an, wenn ich sie in eine while-Schleife stecke, aber wenn ich das in eine watch -n 0.1 ./a.out (schreckliche Wahl), dann zeigt es die Kernzahlen korrekt an. Dasselbe gilt für getconf, es startet jedes Mal neu, wenn es überwacht wird, und zeigt die korrekten Informationen an. Ihr Skript zeigt auch die richtigen Werte.

    – S.Goswami

    20. Dezember 2020 um 21:18 Uhr

  • Aber die Einschränkung ist, wenn ich benutze task -c 0 ./a.outes gibt mir procs=1 statt 4, d.h. es zählt nur die dem Prozess zugeordnete CPU.

    – S. Goswami

    21. Dezember 2020 um 7:42 Uhr

  • @S.Goswami: Genau das soll dieser Code tun; Lassen Sie wissen, wie viele Threads Sie beginnen könnten, um die Anzahl der Kerne in der Affinitätsmaske zu maximieren, mit der Ihr Prozess gestartet wurde. Das ist für einige Szenarien nützlich.

    – Peter Cordes

    28. Juli um 22:20 Uhr

1417110cookie-checkWie erhalte ich die Anzahl der CPUs in Linux mit C?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy