# Núcleo saturado

Un núcleo saturado de un MikroTik RB5009 leído a 10 Hz: por qué el total del equipo lo esconde, la carga saltando entre núcleos y la temperatura.

Source: https://docs.jmrp.io/mikroscope/es/playbooks/cpu/

**En resumen:** un núcleo saturado en el RB5009 de cuatro núcleos se lee como
cerca de un 29 % del equipo, así que es la fila por núcleo, y no el total, la que
muestra un cuello de botella de un solo hilo: aquí un núcleo al 99,8 % mientras
los otros tres estaban ociosos. A 10 Hz se ve al planificador mover la carga entre
núcleos durante unos 20 s antes de asentarse; muestreado una vez por segundo, eso
es una meseta difusa. La carga se provocó a propósito.

Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.2 · Linux 5.6.3 · 2026-09-12 · agente a 10 Hz en un contenedor privilegiado efímero

## Montaje

Un bucle de consola que quema un núcleo y termina por sí solo, sin ningún cambio
de configuración y sin dependencias externas:

```routeros
:local i 0; :while ($i < 4000000) do={ :set i ($i + 1) }
```

Duró 58,8 s.

## Grabación

En tramos de 5 segundos. El agente envía deltas de ticks en bruto; los
porcentajes de abajo se calcularon a partir de ellos después. No hay gráfico: la
ejecución es anterior al historial del almacén InfluxDB de referencia, que
empieza el 2026-09-19.

```text
   t  busy%   per-core busy%          ctxt/s  temp   MHz
   0   22.3   31.8   7.4  40.4   9.6    9192  36.5  1400
   1   30.9   11.7  11.4  89.7  10.6   11325  37.0  1400
   2   29.9   14.3   9.4  19.6  76.0    9476  37.0  1400
   3   29.1    7.4   9.4  17.6  81.6   10805  37.0  1400
   4   29.3    3.1   9.4   4.9  99.8    9257  37.2  1400
   8   28.4    2.2   7.0   4.6  99.8   11947  37.2  1400
  11   33.0   11.8  11.2   9.0  99.7   12222  37.3  1400
```

## Qué mirar

- **Un total de ~29 % es un núcleo de cuatro.** El total del equipo es una trampa;
  mira siempre la fila por núcleo. "29 % de CPU" significa aquí "un núcleo está
  saturado y tres están ociosos", lo que para un cuello de botella de un solo hilo
  es toda la historia.
- **El planificador tardó ~20 s en asentarse.** Los tramos 0–3 muestran el trabajo
  moviéndose entre núcleos (40 % → 90 % → 76 % → 82 %) antes de fijarse en el
  núcleo 3 al 99,8 %. Si muestreas cada 1 s o más despacio ves una meseta difusa;
  a 10 Hz ves la migración.
- **La temperatura lo siguió: de 36,5 a 37,3 °C.** Un núcleo saturado vale ~0,8 °C
  en esta placa con refrigeración pasiva. Poco, pero sigue la carga, y se lee de
  `/sys/class/thermal` sin ninguna llamada a la API.
- **La frecuencia se quedó plana en 1400 MHz.** En este equipo eso es una
  _configuración_, no una observación: el propietario ha fijado el reloj al
  máximo, lo que `/system/routerboard/settings` indica como
  `Warning: cpu not running at default frequency`. En un equipo que escala, el
  campo `freq_khz` es donde verías un tick ocupado que se ganó despacio. El
  agente lee la frecuencia en cada tick y guarda `freq_khz` solo cuando cambia,
  más un latido cada 60 s, así que con un reloj fijo tienes una fila por minuto,
  y con un reloj que escala tienes cada escalón que dure al menos un tick.

## Comprobar el muestreador

Antes de concluir nada de un número de CPU, confirma que
`mikroscope_slipped_total` es 0. Un tick perdido es uno cuya lectura terminó
después de que tocara el siguiente tick, y entonces la propia contabilidad del
muestreador es lo primero de lo que deberías desconfiar.

## Carga en el kernel

La forma contraria: los núcleos no están ocupados, pero el kernel sí. Llegó sola
al RB5009 de referencia, con RouterOS 7.24.4, el 2026-09-23 a las 12:08:50 UTC,
cuando una integración MikroTik de Home Assistant desató una tormenta de
despertares:

- Las interrupciones del temporizador pasaron de unas 2 500 a unas 35 000 por
  segundo, en ráfagas de 20–90 s en un núcleo cada vez, mientras el tiempo de
  usuario y el tráfico seguían planos.
- Apenas se vio en el propio profile de RouterOS, y las columnas de ocupación de
  arriba no la habrían recogido. La tasa de cambios de contexto sí: en ese router
  se movió con las interrupciones del temporizador (r = 1,0).
- Desactivar la integración el 2026-09-24 devolvió el temporizador a unas 2 500
  por segundo en 30 s.

Es un solo evento en un solo router, leído del almacén InfluxDB de referencia, y
aún no tiene caso propio. La regla que la vigila es `mikroscope-wakeup-storm`, en
[Reglas de alerta](https://docs.jmrp.io/mikroscope/es/dashboards/alerts/), que compara la tasa de
cambios de contexto de los últimos diez minutos con las 24 horas anteriores del
propio router.

## Firma

**Provocado a propósito** · 2026-09-12

- Un total del equipo cercano al 100 % dividido entre el número de núcleos — aquí
  ~29 % con cuatro núcleos — con una columna por núcleo al 99,7–99,8 %.
- Antes de asentarse, la carga saltando visiblemente entre núcleos durante
  decenas de segundos.
- Una subida de temperatura de menos de un grado que sigue a la carga.

> **No medido, luego no afirmado**
>
> Una carga multihilo, una carga lo bastante larga como para llegar al equilibrio térmico y
> cualquier cambio de frecuencia del reloj: el reloj del equipo de referencia está fijado, así que
> no se observó qué hace un governor que escala bajo este bucle.

## Véase también

- [Límites de resolución](https://docs.jmrp.io/mikroscope/es/limits/): por qué una muestra de 100 ms resuelve un núcleo
  en escalones del 10 %, y los contadores de la PMU que leen por debajo.
- [Grabar, marcar y dibujar](https://docs.jmrp.io/mikroscope/es/record/): graba una ventana como esta, con marcadores que
  dicen qué más estaba haciendo el router.
- [Cadencias de las fuentes](https://docs.jmrp.io/mikroscope/es/limits/source-floors/): por qué la temperatura se lee al
  1 Hz que declara la zona y la frecuencia solo se guarda cuando cambia.
