Programmgesteuert genaue Informationen zur CPU-Cache-Hierarchie unter Linux abrufen

9

Ich versuche, eine genaue Beschreibung der Datencache-Hierarchie der aktuellen CPU unter Linux zu erhalten: nicht nur die Größe der einzelnen L1 / L2 / L3- (und möglicherweise L4-) Datencaches, sondern auch die Art und Weise, wie sie aufgeteilt oder gemeinsam genutzt werden Kerne.

Auf meiner CPU (AMD Ryzen Threadripper 3970X) verfügt beispielsweise jeder Kern über einen eigenen 32-KB-L1-Datencache und einen 512-KB-L2-Cache. Der L3-Cache wird jedoch von mehreren Kernen innerhalb eines Kernkomplexes (CCX) gemeinsam genutzt. Mit anderen Worten, es gibt 8 verschiedene L3-Caches mit jeweils 16 MB.

Der Abschnitt "Cache" dieses Screenshots von CPU-Z unter Windows ist im Grunde das, was ich herausfinden möchte:

CPU-Z Screenshot

Ich habe kein Problem damit, diese Informationen unter Windows zu erhalten GetLogicalProcessorInformation().

Unter Linux scheint es jedoch sysconf()nur die Cache-Größe pro Kern für L1- und L2-Datencaches ( _SC_LEVEL1_DCACHE_SIZEund _SC_LEVEL2_DCACHE_SIZE) oder die gesamte L3-Cache-Größe ( _SC_LEVEL3_CACHE_SIZE) zu geben.

BEARBEITEN: Die Ausgabe von lstopo unter VMWare . Die virtuelle Maschine verfügt über 8 Kerne. Die L1- und L2-Cache-Informationen sind in Ordnung, aber die L3-Cache-Größe scheint nicht korrekt zu sein:

lstopo Screenshot

François Beaune
quelle
1
Dies kann helfen ... askubuntu.com/a/214302
Mark Setchell
Ich habe mir lstopo angesehen, dieses Projekt ist großartig, aber wahrscheinlich übertrieben für meine Bedürfnisse. Was mich wirklich verwirrt, ist die Verwechslung zwischen Cache-Größen pro Kern und Nicht-pro-Kern-Cache-Größen, die von zurückgegeben werden sysconf(). Wie kann man sie verstehen, wenn wir nicht wissen, ob Caches geteilt werden oder nicht?
François Beaune
Möchten Sie, dass Ihr Programm dies verwendet, um zu entscheiden, wie viele Threads gestartet werden sollen oder welche CPU-Affinitätsmaske festgelegt werden soll? Oder möchten Sie, dass dem Benutzer Informationen angezeigt werden? In beiden Fällen müssen Sie möglicherweise die x86- cpuidAnweisung selbst auf dieser ISA verwenden und möglicherweise sogar einige Details zum Cache-Layout pro Modell einbetten. IDK, wie detailliert die verschiedenen CPUID-Blätter wie sandpile.org/x86/cpuid.htm#level_0000_0004h darstellen können.
Peter Cordes
1
Können Sie lstopoLinux auf Bare Metal ausprobieren ? (zB einen Live-USB booten). Ihr falsches Ergebnis könnte die Schuld der VM sein, daher sollten wir dies ausschließen. Es überrascht nicht, dass es auf meinem i7-6700k-Desktop wie erwartet funktioniert und alle 4 Kerne im selben Paket zeigt, die sich einen L3-Cache teilen. Die Intel Sandybridge-Familie ist jedoch die am weitesten verbreitete und nicht kürzlich geänderte Serie von x86-CPUs.
Peter Cordes
1
Beachten Sie, dass dies lstopoauch für Windows verfügbar ist . lstopoVerwenden Sie die cpuidAnweisung (und möglicherweise die ACPI- SRATTabelle). cpuidist relativ einfach zu bedienen, aber Intel und AMD unterscheiden sich in diesem Aspekt stark. hwloc(zu dem lstopogehört) verfügt über eine API-Schnittstelle, über die Sie die Cache-Topologie sowohl unter Windows als auch unter Linux abrufen können.
Margaret Bloom

Antworten:

3

Ein vollständiges Bild der Cache-Hierarchie finden Sie programmgesteuert, indem Sie Dateien in /sys(sysfs) öffnen .

Jeder "Thread" oder "logische Prozessor" wird durch ein Unterverzeichnis in dargestellt /sys/devices/system/cpu/. In diesem Verzeichnis finden Sie ein Cache-Verzeichnis. Cache-Informationen für den ersten logischen Prozessor finden Sie beispielsweise hier:

$ ls /sys/devices/system/cpu/cpu0/cache/
index0
index1
index2
index3
power
uevent

Jede diesem logischen Prozessor zugeordnete Cache-Entität wird durch ein index[0-9]*Verzeichnis dargestellt. Die Zahl nach dem Index repräsentiert nicht die Ebene. Dieselbe Cache-Entität kann mehrfach unter verschiedenen logischen Prozessoren aufgelistet werden. In diesen Verzeichnissen finden Sie alle Eigenschaften der Cache-Entität (Ebene, Mengen, Zeilengröße usw.).

$ ls /sys/devices/system/cpu/cpu0/cache/index0
coherency_line_size
level
number_of_sets
physical_line_partition
power
shared_cpu_list
shared_cpu_map
size
type
uevent
ways_of_associativity

Die vollständige Dokumentation finden Sie hier .

Um die gewünschte Ausgabe zu erhalten, müssen Sie vor allem Folgendes überprüfen shared_cpu_list:

$ cat /sys/devices/system/cpu/cpu0/cache/index0/shared_cpu_list
0,28

Dies zeigt Ihnen, welche logischen Prozessoren diese Cache-Entität gemeinsam nutzen. Durch Überprüfen aller Entitäten ( /sys/devices/system/cpu/cpu*/cache/index*/) und Entfernen von Duplikaten mit shared_cpu_listkönnen Sie programmgesteuert auf alle benötigten Daten zugreifen.

Beachten Sie, dass Ihr Hypervisor keine genauen Informationen weitergeben muss. Dies zeigt Ihnen nur die Cache-Hierarchie, wie sie der Gastkern sieht.

Mikel Rychliski
quelle