2. Higiene

Asumiendo que nuestro sistema puede mejorar su performance (en la mayor�a ocurre as�), lo primero es corregir ciertos problemas t�picos. En particular:

Llamaremos "pesado" a un proceso que torna lento al sistema. Esto ocurre comunmente porque aqu�l consume muchos recursos de procesamiento (mucho CPU) o consume mucha memoria.

2.1. Consumo excesivo de CPU de un proceso

Muchas veces un proceso que est� fuera de control (por un error en su programaci�n) entra en loops ilimitados que consumen inutilmente el CPU; en otros casos, esto ocurre de manera "normal" durante la ejecuci�n de un proceso frecuente[1]. M�s all� de analizar el por qu� ocurre esto (que es m�s responsabilidad del programador), preocup�monos por detectarlo. Para esto, la manera m�s sencilla quiz� sea emplear el comando:

# ps axu
(Cons�ltese el manual de ps para una explicaci�n de sus opciones.) En particular, estamos interesados en la columna que reza "%CPU". Esta columna proporciona el porcentaje que representa el tiempo de CPU consumido por el proceso respecto al tiempo total de su ejecuci�n.

El siguiente programa se ejecuta durante 20 segundos. Los 10 primeros el proceso no consume CPU, y luego inicia un loop sin descanso hasta que transcurran otros 10 segundos. M�s abajo se muestra el monitoreo del mismo en diversos momentos para un sistema sin carga:

#include <stdio.h>
#include <unistd.h>
#include <time.h>

#define DELAY 10

main()
{
volatile int z;
time_t t;

/* dormir DELAY segundos */
sleep(DELAY);

/* loop infinito durante DELAY segundos */
t=time(NULL);
for(z=0;;z++)
	if(time(NULL)>=t+DELAY)
		break;
return 0;
}
Ejemplo de uso[2]:
$ ./sleep_and_run &
[1] 1194
$ ps axu|head -1
USER   PID  %CPU %MEM   VSZ  RSS STAT START  TIME COMMAND
$ ps axu|grep sleep_and_ru[n]
diego  1141  0.0  0.0  1376  252 S    22:01  0:00 ./sleep_and_run
$ ps axu|grep sleep_and_ru[n]
diego  1141  0.0  0.0  1376  252 S    22:01  0:00 ./sleep_and_run
$ ps axu|grep sleep_and_ru[n]
diego  1141 31.6  0.0  1376  256 R    22:01  0:02 ./sleep_and_run
$ ps axu|grep sleep_and_ru[n]
diego  1141 49.8  0.0  1376  256 R    22:02  0:05 ./sleep_and_run
$ ps axu|grep sleep_and_ru[n]
diego  1141 51.2  0.0  1376  256 R    22:01  0:06 ./sleep_and_run
$ ps axu|grep sleep_and_ru[n]
$
Como se aprecia, la columna %CPU empieza a crecer tras unos momentos hasta alcanzar un valor significativo (51.2%.)

Lamentablemente, este procedimiento no detecta los procesos que de pronto salen de control si �stos ya se han venido ejecutando durante mucho tiempo manteniendo un consumo moderado de CPU (pues en ese caso el %CPU tardar� mucho en hacerse significativo.)[3]

Afortunadamente, existe otra forma muy sencilla de analizar este caso, y consiste en verificar la columna TIME del proceso en diversos momentos. Si se aprecia el ejemplo anterior, se observa que la columna TIME se mantiene estable (en este caso, con 0:00) durante los primeros momentos, y luego r�pidamente se incrementa. Esto es un indicativo claro de que el proceso est� consumiendo mucho de nuestro CPU.

En este punto, el administrador deber� matar inmediatamente al proceso, si �ste resulta ser in�til. En cambio, si el proceso cumple alguna funci�n de utilidad en el sistema, se deber� esperar un tiempo prudencial para que vuelva a la normalidad (deje de consumir tanto CPU) o para que termine.

2.2. Consumo excesivo de Memoria de un proceso

A veces asociado con lo anterior, los procesos pueden consumir demasiada memoria por distintos motivos:

Una manera r�pida de saber si el sistema en su conjunto tiene carencia de memoria f�sica consiste en analizar las columnas 'si' y 'so' bajo '--swap--'[4]:

$ vmstat 2
procs -----------memory---------- ---swap-- -----io----
 r  b   swpd   free   buff  cache   si   so    bi    bo
 0  0      0 321408  11960  95300    0    0    36     9
 0  0      0 321424  11960  95300    0    0     0     4
 0  0      0 321424  11960  95300    0    0     0     0
Si los valores en las columnas mencionadas son cero (quiz� con peque�as excepciones espor�dicas), quiere decir que el sistema tiene suficiente memoria f�sica para los requerimientos DE ESTE MOMENTO. Por lo tanto, el administrador har� bien en analizar la salidad de vmstat en diferentes momentos del d�a, o cuando se ejecutan los procesos cuya lentitud nos preocupa m�s.

Con el fin de analizar la memoria consumida por los procesos, podemos referirnos a las columnas %MEM y RSS de la salida nuestro conocido 'ps axu', que son equivalentes. RSS corresponde a la memoria que el sistema operativo ha otorgado para el proceso, el cual se presenta como porcentaje respecto al total en %MEM.

Siguiendo la idea, es una buena idea analizar qu� procesos consumen mucha memoria y desactivarlos si no son imprescindibles. M�s abajo se explica con detalle qu� se puede hacer si tenemos un sistema con carencia de memoria en el que no podemos desactivar los procesos culpables.

2.3. Re-escritura de procesos pesados

No pretendo entrar al t�pico de optimizar la ejecuci�n de los programas. En mi opini�n, los buenos programadores casi siempre pueden optimizar la ejecuci�n de sus programas para que consuman menos CPU o Memoria, aunque no es una tarea trivial que conlleve poco tiempo. El problema aqu� no es t�cnico, sino de "gerencia": el programador suele ser obligado a liberar una versi�n operativa que r�pidamente pasa a producci�n, y luego se le reasigna a otra actividad sin darle tiempo para (ni obligarle a) que la optimice. Los jefes de IT se sorprender�an gratamente si asignaran a sus buenos programadores exclusivamente a optimizar las aplicaciones por algunos d�as.

Un aspecto imprescindible de resaltar porque resulta evidente, es el consumo excesivo de recursos que hacen los programas desarrollados en lenguajes tipo scripting como el Shell. Si bien es cierto que programar en el Shell (o similares) tiene m�ltiples ventajas, se debe tener en cuenta que una aplicaci�n equivalente reescrita en lenguaje C suele ser de 10 a mil veces m�s veloz, y por tanto mucho menos derrochadora de CPU y Memoria.

El shell tiene su lugar para diversas tareas administrativas y para prototipado de cierta clase de aplicaciones, pero rara vez deber�a constituirse en el lenguaje de una aplicaci�n principal. Como se sabe, muchas veces ocurre que la falta de tiempo o la desidia hace que la gente utilice el prototipo y postergue (para siempre) el desarrollo "en serio".

Notas

[1]

Es aceptable que un proceso consuma mucho CPU por pocos segundos o minutos. Son muy escasos los procesos que consumen mucho CPU durante tiempos extendidos.

[2]

Para compilar el programa, usar algo como: cc -o sleep_and_run sleep_and_run.c

[3]

En algunos sistemas Unix, el %CPU se toma en relaci�n a los �ltimos segundos de ejecuci�n, por lo que no se presenta este inconveniente. Por otro lado, en sistemas multiprocesador el %CPU suele alcanzar 100/N% por proceso o por thread, donde N es el n�mero de procesadores.

[4]

En algunos sistemas Unix esto se separa en columnas de "paginaci�n" tales como 'page-in' y 'page-out'.