Obtenga mediante programación información precisa de la jerarquía de caché de la CPU en Linux

9

Estoy tratando de obtener una descripción precisa de la jerarquía de caché de datos de la CPU actual en Linux: no solo el tamaño de los cachés de datos individuales L1 / L2 / L3 (y posiblemente L4), sino también la forma en que se dividen o comparten núcleos

Por ejemplo, en mi CPU (AMD Ryzen Threadripper 3970X), cada núcleo tiene sus propios 32 KB de caché de datos L1 y 512 KB de caché L2, sin embargo, el caché L3 se comparte entre los núcleos dentro de un complejo central (CCX). En otras palabras, hay 8 cachés L3 distintos, cada uno de 16 MB.

La sección "Caché" de esta captura de pantalla de CPU-Z en Windows es básicamente lo que estoy tratando de descubrir:

Captura de pantalla de CPU-Z

No tengo ningún problema para obtener esta información en Windows con GetLogicalProcessorInformation().

Sin embargo, en Linux, parece que sysconf()solo me da el tamaño de caché por núcleo para cachés de datos L1 y L2 ( _SC_LEVEL1_DCACHE_SIZEy _SC_LEVEL2_DCACHE_SIZE), o el tamaño total de caché L3 ( _SC_LEVEL3_CACHE_SIZE).

EDITAR: salida de lstopo bajo VMWare . La máquina virtual tiene 8 núcleos. La información de caché L1 y L2 está bien, pero el tamaño de caché L3 no parece ser correcto:

Captura de pantalla de lstopo

François Beaune
fuente
1
Esto puede ayudar ... askubuntu.com/a/214302
Mark Setchell
Eché un vistazo a lstopo, este proyecto es increíble pero probablemente exagerado para mis necesidades. Lo que realmente me confunde es la confusión entre los tamaños de caché por núcleo y no por núcleo devueltos porsysconf() . ¿Cómo darles sentido si no sabemos si las memorias caché se comparten o no?
François Beaune
¿Desea que su programa use esto para decidir algo sobre cuántos subprocesos iniciar o qué máscara de afinidad de CPU establecer? ¿O quieres que la información se muestre al usuario? De cualquier manera, es posible que deba usar la cpuidinstrucción x86 usted mismo en ese ISA e incluso incrustar algunos detalles de diseño de caché por modelo. IDK cuántos detalles pueden representar las diversas hojas de CPUID como sandpile.org/x86/cpuid.htm#level_0000_0004h .
Peter Cordes
1
Puedes intentar lstopo Linux en bare metal? (por ejemplo, iniciar un USB en vivo). Su resultado falso podría ser culpa de la máquina virtual, por lo que deberíamos descartarlo. Como era de esperar, funciona como se esperaba en mi escritorio i7-6700k, mostrando los 4 núcleos en el mismo paquete que comparten un caché L3. Pero la familia Intel Sandybridge es la serie de CPU x86 más utilizada y no modificada recientemente.
Peter Cordes
1
Tenga en cuenta que lstopotambién está disponible para Windows . lstopouse la cpuidinstrucción (y tal vez la SRATtabla ACPI ). cpuides relativamente fácil de usar, pero Intel y AMD difieren mucho en este aspecto. hwloc(al que lstopopertenece) tiene una interfaz API que puede usar para obtener la topología de caché tanto en Windows como en Linux.
Margaret Bloom

Respuestas:

3

Se puede encontrar una imagen completa de la jerarquía de caché mediante programación abriendo archivos en /sys(sysfs).

Cada "hilo" o "procesador lógico" está representado por un subdirectorio en /sys/devices/system/cpu/. Dentro de ese directorio encontrarás un directorio de caché. Por ejemplo, la información de caché para el primer procesador lógico se puede encontrar aquí:

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

Cada entidad de caché asociada con ese procesador lógico está representada por un index[0-9]*directorio. El número después del índice no representa el nivel. La misma entidad de caché puede aparecer varias veces en diferentes procesadores lógicos. Dentro de estos directorios puede encontrar todas las propiedades de la entidad de caché (nivel, conjuntos, tamaño de línea, etc.).

$ 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

La documentación completa se puede encontrar aquí .

Lo más importante, para obtener el resultado que desea, deberá inspeccionar shared_cpu_list:

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

Esto le mostrará qué procesadores lógicos comparten esta entidad de caché. Al inspeccionar todas las entidades ( /sys/devices/system/cpu/cpu*/cache/index*/) y eliminar el uso de duplicados shared_cpu_list, puede acceder mediante programación a todos los datos que necesita.

Tenga en cuenta que su hipervisor no está obligado a transmitir información precisa. Esto solo le mostrará la jerarquía de caché tal como la ve el kernel invitado.

Mikel Rychliski
fuente