- Entender la topología NUMA con lscpu y alinear CPU, memoria y dispositivos es clave para afinar rendimiento con perf y numactl.
- La salida de perf kvm stat, especialmente eventos como PAUSE_INSTRUCTION, revela ineficiencias en la planificación de vCPUs en KVM.
- PerfInsights en Azure automatiza la recogida y análisis de datos de CPU, memoria, red y disco, facilitando el diagnóstico en VMs Linux.
- En servidores Cascade Lake, opciones de BIOS como SNC y el perfil de rendimiento aportan mejoras medibles en aplicaciones HPC.
Cuando te pones a exprimir el rendimiento en sistemas NUMA, rápidamente descubres que no basta con lanzar la carga y mirar el uso de CPU. Herramientas como perf, numactl, ajustes de BIOS (SNC, precapturadores, perfiles de rendimiento) y utilidades especializadas como PerfInsights en Azure marcan la diferencia entre un sistema mediocre y uno afinado de verdad.
En este artículo vamos a hilar fino: veremos cómo medir con perf y numactl en escenarios reales (virtualización KVM, redes de 40 GbE, cargas HPC), cómo interpretar salidas complejas (VM-EXIT, topología NUMA, ancho de banda de memoria) y cómo encaja todo esto con herramientas de diagnóstico como PerfInsights y los ajustes de BIOS en servidores Cascade Lake para workloads de alto rendimiento.
Topología NUMA y CPU: leyendo bien la salida de lscpu
El primer paso antes de meterse con perf, numactl y ajustes finos es entender cómo está organizado el hardware. En un servidor típico x86_64 moderno, la salida de lscpu te da casi todo lo que necesitas saber para planificar afinado y pruebas.
Imagina un sistema con esta configuración: arquitectura x86_64, 40 CPUs lógicas, 4 sockets físicos, 10 núcleos por socket, sin Hyper-Threading (1 hilo por núcleo) y 4 nodos NUMA. La información clave la ves con lscpu:
- Architecture: x86_64
- CPU(s): 40
- Thread(s) per core: 1
- Core(s) per socket: 10
- Socket(s): 4
- NUMA node(s): 4
- Model name: Intel(R) Xeon(R) CPU E7-4870 @ 2.40GHz
Más importante todavía es el mapeo de núcleos a nodos NUMA, porque condiciona totalmente cómo vas a usar numactl para fijar CPU y memoria:
- NUMA node0 CPU(s): 0,4,8,12,16,20,24,28,32,36
- NUMA node1 CPU(s): 2,6,10,14,18,22,26,30,34,38
- NUMA node2 CPU(s): 1,5,9,13,17,21,25,29,33,37
- NUMA node3 CPU(s): 3,7,11,15,19,23,27,31,35,39
Con esta distribución, cada nodo NUMA agrupa un conjunto de CPUs lógicas que comparten memoria local. Si una carga se ejecuta en CPUs de node0 pero su memoria se reserva en node2, cada acceso remoto atraviesa el enlace de interconexión (QPI/UPI), con más latencia y menos ancho de banda efectivo. Aquí es donde entran en juego numactl y las políticas de afinidad.
Medir eventos de virtualización con perf kvm stat
En entornos con KVM, una de las formas más potentes de diagnosticar problemas de rendimiento es usar perf kvm stat para analizar los VM-EXIT. Cada vez que una vCPU sale al hipervisor, se produce un coste; si se repite demasiado, el rendimiento de la VM se hunde.
Un informe típico de perf kvm stat report puede verse así (simplificando formato, pero manteniendo los datos clave):
perf kvm stat report Analyze events for all VMs, all VCPUs: VM-EXIT Samples Samples% Time% Min Time Max Time Avg time EXTERNAL_INTERRUPT 365634 31.59% 18.04% 0.42us 58780.59us 204.08us MSR_WRITE 293428 25.35% 0.13% 0.59us 17873.02us 1.80us PREEMPTION_TIMER 276162 23.86% 0.23% 0.51us 21396.03us 3.38us PAUSE_INSTRUCTION 189375 16.36% 11.75% 0.72us 29655.25us 256.77us HLT 20440 1.77% 69.83% 0.62us 79319.41us 14134.56us VMCALL 12426 1.07% 0.03% 1.02us 5416.25us 8.77us EXCEPTION_NMI 27 0.00% 0.00% 0.69us 1.34us 0.98us EPT_MISCONFIG 5 0.00% 0.00% 5.15us 10.85us 7.88us Total Samples: 1157497, Total events handled time: 413728274.66us
La clave está en fijarse tanto en el porcentaje de muestras como en el Time% y el tiempo medio. Por ejemplo, el evento PAUSE_INSTRUCTION debería verse de forma esporádica en un entorno sano, pero en este ejemplo aparece con:
- Samples%: 16.36 %
- Time%: 11.75 %
- Avg time: 256.77 µs
Una alta tasa de PAUSE_INSTRUCTION suele indicar que las vCPUs se pasan la vida esperando (spinlocks, espera activa, contención), y a menudo es síntoma de que el host no programa bien las vCPUs físicas y virtuales. El resultado práctico es que las VMs parecen “lentas” aunque el uso de CPU no esté al 100 %.
En una situación así, es recomendable plantearse varias acciones concretas sobre el host KVM:
- Reducir el número de VMs en ejecución si estás claramente sobrecomprometido en CPU.
- Quitar vCPUs sobrantes en VMs que no las aprovechan, para bajar la presión del planificador.
- Ajustar la afinidad de vCPUs a CPUs físicas y nodos NUMA, de forma que cada VM tenga una topología coherente.
Otros eventos en la salida de perf kvm stat que pueden avisar de problemas incluyen EXTERNAL_INTERRUPT, EPT_MISCONFIG, EXCEPTION_NMI y tasas anómalamente altas de MSR_WRITE. Cada uno apunta a causas distintas (interrupciones del host, problemas de EPT, excepciones, uso excesivo de MSRs), así que merece la pena revisar la distribución completa, no solo un tipo de evento.
Rendimiento de red y NUMA: iperf3, afinidad y numactl
La relación entre rendimiento de red y topología NUMA es mucho más fuerte de lo que mucha gente piensa. Un caso práctico: dos servidores con Xeon E5-2667, dos sockets físicos, 6 núcleos por socket con Hyper-Threading activado (24 CPUs lógicas), 32 GB de DDR3 y dos nodos NUMA bien definidos (uno por socket).
En esta configuración, las tarjetas de red de 40 GbE están conectadas físicamente al nodo NUMA 0. Al lanzar pruebas de iperf3 entre las dos máquinas, se observa:
- Sin fijar afinidad de CPU, ni en cliente ni en servidor, el throughput no pasa de ~22 Gbps.
- Cuando se fija afinidad de CPU en ambos extremos, se alcanza ~36 Gbps, mucho más cercano a lo esperado para 40 GbE.
Esta diferencia tan grande prácticamente solo se explica por la arquitectura de memoria/bus y el posicionamiento NUMA de la NIC. El tráfico que entra por una interfaz situada en node0 rinde mejor cuando el proceso que lo maneja (iperf3 en este ejemplo) corre en CPUs ligadas a ese mismo nodo y, a ser posible, con memoria local.
Con numactl se pueden probar distintas políticas:
- CPU y memoria fijadas al mismo nodo que la NIC: suele ser el escenario más rápido; en el ejemplo, se obtienen ~30-32 Gbps, por debajo del caso con afinidad pura de CPU pero claramente por encima del escenario sin afinidad.
- CPU y memoria en el nodo remoto respecto a la NIC: el rendimiento cae, pero curiosamente no tanto como el caso original sin afinidad, quedándose en ~28-29 Gbps.
Esto revela que no basta con “atar todo al nodo de la NIC” a ciegas: la interacción entre el planificador del kernel, las colas de interrupciones de la NIC, la política NUMA y el propio iperf3 puede dar resultados contraintuitivos. Aun así, la pauta general es clara: mantener CPU e I/O lo más locales posible al nodo NUMA de la NIC suele ser la mejor apuesta.
Eventos útiles de perf para entender el cuello de botella
Cuando se sospecha que la limitación de rendimiento viene de la arquitectura (memoria, QPI/UPI, uncore), perf puede ayudar a medir mucho más allá de las instrucciones de la CPU. Sin embargo, no todos los eventos están disponibles ni expuestos igual según modelo de procesador y kernel.
Al intentar usar eventos como uncore_imc_0/cas_count_read/ o uncore_qpi_0/clockticks/, es posible que perf devuelva que no están soportados. Esto suele deberse a:
- El modelo de procesador (por ejemplo, ciertas variantes de Sandy Bridge-EP) no expone esos contadores uncore de la misma forma.
- La versión de kernel o de perf no incluye los descriptores de esos eventos uncore.
- Falta de módulos de kernel o restricciones del sistema para acceder a contadores de bajo nivel.
Aun sin esos eventos, puedes tirar de contadores de CPU genéricos y de memoria (ciclos, instrucciones, LLC misses, referencias a memoria, etc.) para correlacionar consumo, latencias y comportamiento de la caché. Si el problema está en el cruce de nodos NUMA, también verás un aumento claro de faltas de último nivel y más ciclos por instrucción.
PerfInsights en Azure: diagnóstico automatizado en VMs Linux
En el mundo de Azure, Microsoft ofrece PerfInsights Linux, una herramienta de diagnóstico de rendimiento “todo en uno” para máquinas virtuales Linux. Está pensada tanto para análisis continuos como para sesiones puntuales cuando ya sospechas de un problema.
PerfInsights dispone de dos modos principales:
- Diagnóstico continuo: recopila datos cada 5 segundos y genera recomendaciones cada 5 minutos, muy útil para detectar picos de uso.
- Diagnóstico bajo demanda: se lanza ad hoc cuando el sistema ya está sufriendo, recopilando un snapshot mucho más detallado para análisis forense.
Está enfocado a máquinas virtuales Linux en Azure, incluyendo tamaños HPC (H-Series, N-Series), y genera informes claros que sirven tanto al administrador como al soporte de Microsoft.
Escenarios de uso: CPU, memoria, disco y más
Con PerfInsights puedes abordar una gran variedad de escenarios de problemas de rendimiento, desde picos de CPU y memoria hasta cuellos de botella en disco o red. Para el modo continuo, algunas capacidades clave son:
- Detección de uso elevado de CPU, con identificación de procesos top consumidores en los periodos problemáticos.
- Análisis de uso alto de memoria, listando quién se está comiendo la RAM.
- Monitorización de uso de disco físico y procesos que más lo explotan.
Además, PerfInsights recopila mucha información pasiva del sistema que apenas afecta al rendimiento mientras corre; es precisamente el tipo de información que un buen ingeniero mira cuando quiere entender el contexto completo de la VM.
Qué recopila PerfInsights en una VM Linux
La herramienta junta en un solo paquete toneladas de datos útiles sobre la máquina virtual, el sistema operativo, el hardware virtual y los grandes consumidores de recursos. Entre otros, incluye:
- Sistema operativo:
- Distribución y versión de Linux.
- Versión de kernel y módulos relevantes.
- Información sobre drivers importantes.
- Registros de la extensión Azure HPC Driver VM (en escenarios HPC).
- Estado y configuración de SELinux en entornos que lo usan.
- Hardware:
- Listado de dispositivos PCI (en la mayoría de distros, salvo particularidades de Debian).
- Salida de
lscpucompleta. - Volcado de la tabla BIOS de gestión del sistema (SMBIOS).
- Procesos y memoria:
- Lista de procesos con nombre, memoria utilizada y ficheros abiertos.
- Memoria física total, libre y disponible.
- Estado del swap (total, libre, usado).
- Perfiles de uso de CPU de procesos cada 5 segundos.
- Perfiles de uso de memoria de procesos cada 5 segundos.
- Límites de usuario (ulimits) relacionados con memoria.
- Configuración NUMA detectada por el sistema.
- GPU (en VMs con aceleración):
- Salida de
nvidia-smi. - Diagnósticos de Nvidia DCGM.
- Volcados de depuración de Nvidia.
- Salida de
- Red:
- Interfaz de red y estadísticas por adaptador.
- Tabla de rutas de red.
- Puertos abiertos y estados.
- Claves de partición InfiniBand e info de
ibstaten escenarios HPC.
- Almacenamiento:
- Dispositivos de bloque visibles.
- Particiones existentes.
- Puntos de montaje y opciones.
- Detalles de volúmenes MDADM y LVM.
- Perfiles de actividad de disco en intervalos de 5 segundos.
- Registros:
- Logs del sistema como
/var/log/messages,syslog,kern.log,cron.log,boot.log,yum.log,dpkg.log, etc. - Histórico de
sysstatosacuando está disponible. - Registros de cloud-init, gpu-manager, waagent y extensiones de Azure.
- Configuración de waagent (
/etc/waagent.conf). - Salida de
journalctlde los últimos cinco días.
- Logs del sistema como
- Metadatos de la instancia de Azure, útiles para correlacionar tamaño de VM, discos, red y configuración de la plataforma.
Para escenarios HPC, PerfInsights añade datos extra especializados, especialmente alrededor de GPU, InfiniBand, NUMA y drivers específicos, algo crítico cuando estás persiguiendo microcuellos de botella en un cluster.
Motor de reglas y tipos de hallazgos
Una de las ventajas de PerfInsights es que no solo recolecta datos, sino que ejecuta un motor de reglas que analiza los indicadores y genera conclusiones y recomendaciones. En el informe HTML, estas reglas aparecen organizadas por categorías.
Cada regla incluye:
- Resultado: descripción de qué se ha detectado.
- Recomendación: pasos sugeridos o documentación para profundizar.
- Nivel de impacto: el peso potencial del problema sobre el rendimiento global.
Las categorías cubren muchos frentes ligados a la salud del sistema:
- Uso elevado de recursos (CPU, memoria, disco), con enfoque especial en periodos sostenidos.
- Almacenamiento, detectando configuraciones subóptimas.
- Memoria y NUMA, importante para cargas HPC.
- GPU, con foco en drivers, errores y configuración.
- Red, incluyendo InfiniBand y parámetros relevantes.
- Sistema en general: opciones de kernel, servicios, parámetros de entorno.
Esto complementa muy bien el trabajo manual que harías con perf, numactl, lscpu o herramientas de benchmarking, dándote una capa de interpretación automática que ahorra bastante tiempo.
Ejecución de PerfInsights: requisitos y soportes
Para usar PerfInsights en Linux hay que asegurarse de que la VM cumple con una serie de requisitos básicos y de que se lanza la herramienta en la máquina afectada, no en otra.
- Debe ejecutarse dentro de la VM con problemas, con permisos adecuados (normalmente usando
sudo). - Requiere Python 3.6 o posterior. En RHEL 8, por ejemplo, no viene de serie, así que hay que instalarlo con
yum install python3. - Soporta distribuciones como Oracle Linux (6.10, 7.x), RHEL (7.4-7.9, 8.x), Ubuntu (16.04, 18.04, 20.04, 22.04), Debian (9, 10, 11), SLES (12 SP5, 15 SP1-SP6), AlmaLinux 8.4/8.5 y Azure Linux 2.0/3.0.
Hay algunas peculiaridades conocidas: en distros basadas en Debian no siempre se recopila toda la información PCI, y en ciertos sabores la información LVM puede salir parcial. Aun así, el grueso de datos relevantes para CPU, memoria, red y disco se recoge sin problemas.
Cómo lanzar PerfInsights en modo independiente
Además de la integración con el portal de Azure (extensión Azure Performance Diagnostics), PerfInsights se puede ejecutar como herramienta independiente descargando un tarball y lanzando un script Python.
- Descargas el paquete y lo descomprimes:
wget https://download.microsoft.com/download/9/F/8/9F80419C-D60D-45F1-8A98-718855F25722/PerfInsights.tar.gz tar xzvf PerfInsights.tar.gz
- Entras en la carpeta y lanzas el script principal para ver las opciones:
cd <carpeta PerfInsights> sudo python perfinsights.py
La sintaxis básica para correr un escenario es algo como:
sudo python perfinsights.py -r <ScenarioName> -d <duración><H|M|S> [opciones]
Por ejemplo, para un análisis rápido de 1 minuto y resultados en /tmp/output:
sudo python perfinsights.py -r quick -d 1M -a -o /tmp/output
Para un análisis de VM lenta durante 5 minutos y subir los resultados a una cuenta de almacenamiento de Azure:
sudo python perfinsights.py -r vmslow -d 300S -a -t <StorageAccountName> -k <StorageAccountKey> -i <URI completo de la VM>
Y para un análisis HPC de 60 segundos, con subida automática:
sudo python perfinsights.py -r hpc -d 60S -a -t <StorageAccountName> -k <StorageAccountKey> -i <URI completo de la VM>
Al terminar la ejecución, la herramienta genera un archivo PerformanceDiagnostics_yyyy-MM-dd_hh-mm-ss-fff.tar.gz en la misma carpeta (salvo que hayas especificado una ruta de salida). Dentro encontrarás el informe HTML PerfInsights Report.html, que es el que vas a revisar o enviar al soporte de Microsoft si es necesario.
Navegando por el informe HTML de PerfInsights
El informe está organizado en pestañas temáticas para que puedas ir directo a lo que te interesa. Algunas secciones claves son:
- Información general: muestra detalles básicos de la VM, de la ejecución y un resumen de las conclusiones globales.
- Conclusiones: agrupa recomendaciones de todas las secciones, ordenando por nivel de impacto; esta es la pestaña que conviene revisar a fondo si el sistema tiene problemas serios.
- CPU: ofrece gráficos y listas con periodos de alta CPU y procesos que más contribuyen a ello; ideal para cruzar con mediciones de
perfo salidas detop. - GPU: en VMs con GPU, muestra estado de drivers, errores, utilización y posibles problemas con el hardware acelerador.
- Red: recoge la configuración, estadísticas y hallazgos específicos (incluyendo temas de InfiniBand en el escenario HPC).
- Almacenamiento: presenta tanto conclusiones como secciones detalladas de dispositivos de bloque, particiones, LVM, MDADM y más.
- Linux: lista procesos, agentes, info de PCI, CPU, GPU y drivers LIS, proporcionando una radiografía general del sistema.
Cuando estás combinando pruebas con perf/numactl, análisis de red con iperf3 y revisión de logs, este informe sirve como pieza central para no perderte ningún factor relevante.
Ajustes de BIOS en servidores Cascade Lake para HPC
En entornos on-premise o bare metal, el rendimiento final no depende solo del sistema operativo y de herramientas como perf, sino también de cómo está configurado el BIOS. En servidores Dell EMC PowerEdge C6420 con procesadores Intel Xeon Scalable de 2ª generación (Cascade Lake), algunos interruptores de BIOS tienen un impacto medible en cargas HPC.
Cascade Lake soporta hasta 28 núcleos por socket, seis canales de memoria DDR4 hasta 2933 MT/s y el conjunto de instrucciones AVX-512, capaces de 32 FLOP DP por ciclo. Además, introduce VNNI (Vector Neural Network Instructions) para acelerar inferencia de IA con operaciones de 8 bits, y trae mitigaciones de hardware para ciertas vulnerabilidades de canal lateral.
Lo interesante desde el punto de vista de ajuste fino es que, al ser compatible en zócalo con Skylake, muchas opciones de BIOS son compartidas, lo que permite reaprovechar buenas prácticas de tuning anteriores.
Opciones clave de BIOS: precapturadores y Sub-NUMA Clustering
Entre los parámetros ajustables más relevantes para HPC destacan tres: precaptura de línea de caché adyacente, precapturador de software y SNC (Sub-NUMA Clustering), además de los perfiles globales de sistema.
- Precaptura de línea de caché adyacente:Este mecanismo de hardware trae automáticamente una línea de caché adicional, formando un sector de 128 bytes (dos líneas de 64 bytes) aunque solo se haya solicitado una. Cuando está habilitado, puede mejorar ciertos accesos secuenciales, pero su impacto real depende de la carga.
- Precapturador de software:Consiste en usar instrucciones explícitas de precarga (por ejemplo, de memoria principal a L2 y luego a L1) para evitar parones esperando a memoria. Con la opción activada, el procesador puede buscar una línea de caché adicional por cada acceso. Sin embargo, en muchas pruebas HPC su efecto directo en el rendimiento es mínimo.
- SNC (Sub-NUMA Clustering):Al activar SNC, un único socket se divide lógicamente en dos dominios NUMA, cada uno con la mitad de los núcleos y la mitad de la memoria. Esto se parece al antiguo Cluster-on-Die, pero con implementaciones mejoradas. En un servidor de dos sockets con SNC habilitado, el sistema operativo ve cuatro nodos NUMA en lugar de dos, con dos pares más cercanos entre sí (los que comparten socket) y dos más lejanos (los que cruzan UPI al otro socket). Esto se comprueba fácilmente con herramientas como
numactl -H.
Además, los perfiles de sistema del BIOS (Rendimiento, Rendimiento por vatio DAPC, Rendimiento por vatio OS) agrupan opciones como Turbo, C-states, C1E, gestión de P-state, frecuencia uncore, etc. Para HPC puro, suele compensar priorizar el perfil de “Rendimiento” frente a perfiles orientados a eficiencia energética.
Impacto en benchmarks y aplicaciones HPC
Para cuantificar el efecto de estos ajustes, se han medido varios benchmarks y aplicaciones típicas de HPC: STREAM (ancho de banda de memoria), HPL (Linpack de alto rendimiento), Fluent y WRF. Las conclusiones que salen son bastante claras:
- En HPL (con tamaño de problema ~90 %, N=144476), la diferencia de rendimiento por activar o desactivar el precapturador de software es menor al 1 %. SNC tampoco altera significativamente el resultado (algo así como un 0,5 % mejor con SNC desactivado), mientras que el perfil de sistema “Rendimiento” llega a rendir hasta un 6 % por encima de perfiles orientados a ahorro (OS/DAPC).
- En STREAM Triad, habilitar SNC consigue hasta un 3 % más de ancho de banda de memoria, mientras que la precaptura de software prácticamente no introduce variaciones. Los perfiles de sistema tampoco muestran grandes diferencias en este caso concreto.
- En WRF (dataset conus2.5km con
namelist.inputpor defecto), con SNC activado se ve alrededor de un 2 % de mejora en el paso de tiempo medio, y el perfil de rendimiento aventaja en torno a un 1 % a PerformancePerWattDAPC. - En Fluent (casos Ice_2m, Combustor_12m, Aircraft_Wing_14m, Exhaust_System_33m), la mejora con SNC habilitado llega a ser de hasta 4 %, la captura previa de software no tiene efecto apreciable, y el perfil de rendimiento puede ser entre un 2 y un 4 % mejor que los perfiles DAPC/OS.
Todo esto se traduce en una serie de recomendaciones prácticas para clusters HPC con estos procesadores:
- Dejar el precapturador de software habilitado, ya que no penaliza y es la opción por defecto.
- Activar SNC cuando esté disponible, porque aporta mejoras del 2-4 % en varias aplicaciones y en ancho de banda de memoria.
- Elegir el perfil de sistema “Rendimiento” como opción estándar para nodos de cálculo.
- Valorar desactivar Hyper-Threading en clusters de propósito general, salvo que la aplicación demuestre beneficios claros con HT activo.
- Si la plataforma ofrece la característica de corrección de dispositivo DRAM doble adaptable (ADDDC) para DIMMs x4 (32/64 GB), dejarla desactivada para cargas HPC, ya que puede penalizar algo el rendimiento y no es necesaria en muchos escenarios de cómputo.
Junto con esto, siempre es buena idea combinar mediciones de perf, numactl, PerfInsights y benchmarks para validar que los cambios de BIOS se traducen en mejoras reales para tus workloads concretos.
Visto todo lo anterior, queda bastante claro que sacar partido a plataformas modernas pasa por unir varias piezas: conocer la topología NUMA real con lscpu, usar numactl para alinear CPU, memoria y dispositivos, interpretar bien la salida de perf (especialmente en entornos KVM con VM-EXIT, PAUSE_INSTRUCTION y compañía), aprovechar herramientas de diagnóstico como PerfInsights en Azure para automatizar la recogida y análisis de datos y, en hardware como los Xeon Cascade Lake, jugar con opciones de BIOS como SNC y perfiles de rendimiento. Todo este ecosistema de métricas y ajustes, bien entendido y aplicado con criterio, marca la frontera entre un sistema que simplemente “funciona” y uno que realmente rinde al nivel que el hardware permite.