lunes, 27 de junio de 2011

/proc/loadavg

El archivo /proc/loadavg contiene información acerca de la carga del sistema. Específicamente, los siguientes 5 indicadores:
  1. Promedio de procesos activos en el último minuto
  2. Promedio de procesos activos en los últimos 5 minutos
  3. Promedio de procesos activos en los últimos 15 minutos
  4. Procesos que estan planificados para ejecutarse/total de procesos
  5. Process ID del proceso más recientemente ejecutado
Los 3 primeros indicadores, son en los que nos centraremos en esta entrada. Ellos representan los promedios aproximados exponenciales de la carga del sistema. Mientras mayores sean estos valores, más cargado se encuentra la máquina. Estos promedios son los mostrados por diversos comandos de Linux como uptime, w, top y procinfo.


Forma de cálculo

La fórmula para calcular el valor actual de la carga es la de medias móviles amortiguadas exponencialmente, utilizada ampliamente en Estadística y Economía:

load(t) = load(t-1) * EXP_M + (1 - EXP) * x

En donde:
  • x = número de procesos activos (procesos que están en cola para ser ejecutados)
  • EXP_M = 1/exp(5seg/(60seg*m)), siendo m = 1, 5 y 15 (minutos)
Para 1 minuto:
EXP_1 = 1 / exp(5 seg/1 min) = 1/exp(1/12) =~ 0.91

Para 5 minutos:
EXP_5 = 1 / exp(5 seg/5 min) = 1/exp(1/60) =~ 0.98

Para 15 minutos:
EXP_15 = 1 / exp(5 seg/15 min) = 1/exp(1/180) =~ 0.99

El valor de 5seg involucrado en el cálculo de EXP_M tiene que ver con la frecuencia de cálculo, que es de 5HZ, lo cual implica que la función de cálculo se ejecuta cada 5000ms o 5seg.

Cuanto más grande es EXP_M, la historia "permanece" por más tiempo. Se puede decir que la historia tiene un "valor de decaimiento" de 0.91 para el primer caso, 0.98 para el segundo y 0.99 para el tercero.

Una buena discusión del uso de medias móviles ponderadas exponencialmente y su comparación con otro tipo de medias, se puede leer aquí.


Implementación en Linux

En realidad, estando el kernel de Linux ampliamente optimizado, en vez de representar los valores de EXP_M en punto flotante, se representan en punto fijo, pues los cálculos se realizan en el espacio de kernel y no en espacio de usuario.

La función de cálculo de la carga se encuentra definida en <kernel/timer.c> y su prototipo es:
static inline void calc_load(unsigned long ticks)
Esta función, internamente hace uso de la macro CALC_LOAD(load, exp, n), definida en <linux/sched.h&gt.

La función que imprime los valores de carga en /proc/loadavg se encuentra definida en linux/fs/proc/proc_misc.c, y su prototipo es:
static int loadavg_read_proc(char *page, char **start, off_t off,
                 int count, int *eof, void *data) 
Esta función está constantemente ejecutándose en el sistema, y es así como cada vez que ejecutamos el comando uptime (por ejemplo) podemos acceder a estos valores.


Más información

No es mucha la información que se consigue sobre este tema en la red. Sin embargo dejo un par de enlaces útiles:

BULMA: ¿Cómo se calculas los promedios de loadavg en Linux?. link
TeamQuest: UNIX Load Average. link

No hay comentarios: