"Christmas - the time to fix the computers of your loved ones" « Lord Wyrm

Erkennen wieviele logische CPUs ein OS Kernel adressieren kann (C/C++)

GrandAdmiralThrawn 15.09.2021 - 11:12 3226 0
Posts

GrandAdmiralThrawn

XP Nazi
Avatar
Registered: Aug 2000
Location: BRUCK!
Posts: 3692
Bin unlängst auf einen Fall gestoßen, wo ein C++ Programm von sich aus ein Maximum von adressierbaren CPUs bzw. dann abzusetzenden Worker Threads pro NUMA Pool definiert hat.

Da war ein meines Erachtens nach recht blöder Check drin: Max. 64 Threads bei x86_64 und 32 auf allem anderen. Insbesondere in Bezug auf 64-bit PowerPC und ggf. 64-bit ARM ist das eher blöd? Vor allem weil das ja für moderne Betriebssysteme längst schon nicht mehr wahr ist, auch auf x86_64 nicht. Es gibt ja schon x86 CPUs (einzelne NUMA Knoten in der Topologie!) mit 128 Threads und das wird noch wachsen.

Viel früher (Linux 2.4, Win XP/Vista, FreeBSD 8 oder 9) hatten Betriebssysteme ja meist ein Maximum von 32 logischen CPUs auf 32-bit Systemen und oft 64 auf 64-bit Systemen, umgesetzt als Bitvektor bzw. Bitmap. Der Bitvektor war halt einfach nur 32 oder 64 Bits breit.

Neuere Systeme haben oft 256 auf die klassische Weise adressierbare logische CPUs. Auf einer FreeBSD Shell z.B.:
Code:
$ sysctl kern.smp.maxcpus
kern.smp.maxcpus: 256

Ich will programmatisch in z.B. C++ erkennen können, wie groß dieses Bitvektor-Adreßfeld des laufenden Betriebssystems ist, egal ob auf Systemen ohne NUMA Unterstützung oder auf solchen mit einer selbigen - dann halt eine Erkennung eines Felds pro NUMA Knoten. Ich kann dann ja noch die NUMA Knoten auslesen, um die Gesamtanzahl zu kriegen, aber darum geht's mir hier nicht. Ich will nur die Breite dieses Bitvektors kennen.

Funktionen wie GetMaximumProcessorCount() unter Windows machen das nicht; Der gibt einfach "4" aus, wenn meine tatsächliche Maschine halt nur 4 CPUs hat. Bzw. 4 pro NUMA Knoten, so vorhanden. Er gibt nicht das Maximum des Kernels aus.

Optimal wäre das plattformübergreifend, also BSD/Linux/Windows/macOS/irgendwas. Falls das halt geht. Dann könnte ich einfach diesen Wert auslesen und das Maximum dementsprechend setzen. Und wenn das Betriebssystem 4096 kann, dann setze ich es einfach auf 4096... Der bestehende Code skaliert das dann eh von selbst je nach tatsächlich vorhandenen logischen CPUs hoch, da brauch ich nichts weiter tun.

Es wäre auch ok, wenn es Codepfade für unterschiedliche Betriebssysteme braucht, dann trenne ich das in C++ halt per Präprozessordirektiven.

Kann man das überhaupt irgendwie auslesen?

Danke!
Bearbeitet von GrandAdmiralThrawn am 15.09.2021, 11:20
Kontakt | Unser Forum | Über overclockers.at | Impressum | Datenschutz