MULTITAREA
El kernel de Linux, como el de la mayoría de los sistemas operativos modernos, es multitarea. Eso quiere decir que se están ejecutando varios programas al mismo tiempo.
En realidad esto no ocurre exactamente así. Lo que se hace es poner los programas en una cola y, uno por uno, el microprocesador los ejecuta durante una cierta cantidad de tiempo. Una vez agotado éste el microprocesador interrumpe la tarea dejándola a medias y da paso a la siguiente. A esta cantidad de tiempo se le denomina quantum o time slice, y no tiene por qué ser constante.
Una buena analogía podría ser el cocinero de un bar preparando varios platos a la vez: un bocata de lomo, una de callos, una ensalada mixta... Ahora parto el pan, enciendo la sartén, mientras se calienta lavo la lechuga, etc.
Si el quantum es suficientemente pequeño la impresión subjetiva para un observador lento, como el ser humano, es de que en vez de un procesador rápido ejecutando tareas alternativamente tenemos un procesador lento para cada una ellas (varios cocineros en la misma cocina haciendo lentamente cada uno un solo plato).
LA CONMUTACIÓN DE TAREAS TIENE UN COSTE
La multitarea no es gratis: implica una sobrecarga del procesador. En efecto, desalojar una tarea y cargar la siguiente es un trabajo extra. Esta operación se denomina 'cambio de contexto' o 'conmutación de tareas'. Sería más rentable en términos de CPU ejecutar los programas por completo, uno por uno, que partirlos en 'rodajas' e ir saltando de uno a otro. Sin embargo, el sistema perdería en interactividad, no podríamos tener varias ventanas abiertas o, en el caso de un servidor, atender a varias peticiones simultáneamente.
LATENCIA Y RENDIMIENTO
Supongamos que nuestro cocinero tiene que pelar 20 kilos de gambas y deshuesar 20 kilos de aceitunas. ¿Cómo se planifica el trabajo?
En un caso extremo primero pelaría todas las gambas, se lavaría las manos para no mezclar sabores y después deshuesaría todas las aceitunas. Lo representaremos así:
GGGGGGGGGGGGGGGGGGGGGG... C AAAAAAAAAAAAAAAAAAAAAA...
En el extremo opuesto, pelaría una gamba, se lavaría las manos, deshuesaría una aceituna, se lavaría las manos... gamba, aceituna, gamba, aceituna... Lo representaremos así:
GCACGCACGCACGCACGCACGCACGCACGCACGCACGCACGCACGCACGCACGCACGCAC...
La 'C' representa el cambio de contexto: lavarse las manos, cambiar de utensilio...
Al mismo tiempo, un camarero recoge las peticiones de los clientes: "¡una de gambas!"... "¡una de aceitunas!"... y las translada a la cocina.
En el primer caso, supongamos que entra un cliente y pide una ración de gambas. No hay problema, enseguida se le sirve. Pero, ¿y si pide aceitunas? El camarero no podría servirla hasta que todas las gambas estuvieran peladas. En este caso la latencia, que es el tiempo que pasa desde que se hace una petición hasta que ésta es atendida, sería muy alta.
En el segundo caso, pida lo que pida el cliente, estará disponible en poco tiempo, además prácticamente igual en ambos casos. La latencia será baja, pero a un coste: debido a los cambios de contexto se producirá una disminución del rendimiento, entendido como la parte del tiempo durante el cuál la CPU está haciendo tareas directamente productivas, en lugar de labores de soporte.
Evidentemente en este caso la solución ideal sería un término medio, que dependería del tamaño de las raciones y de la distribución estadística de las peticiones. La teoría de colas es la rama de la matemática que se encarga de estudiar estas situaciones y de darles soluciones óptimas.
Como se puede ver, latencia y rendimiento son opuestos. Por esta razón no es correcto afirmar que los kernels rt dan más rendimiento. Todo lo contrario, al bajar la latencia empeoran el rendimiento de la máquina y, por lo tanto, son una elección pésima para sistemas que no necesiten respuestas superrápidas como, por ejemplo, servidores web o de bases de datos.
Por el contrario, los kernels de baja latencia son ideales en situaciones donde se necesite la máxima velocidad de respuesta a los estímulos externos, como sistemas de control industrial o aplicaciones multimedia interactivas, sabiendo que estamos sacrificando parte de la potencia de la máquina en garantizar esa rápida reacción.
PRIORIDADES
Una opción interesante en sistemas multitarea es dar distintas prioridades a las tareas, de tal forma que las más importantes reciban más tiempo del procesador y las menos importantes menos. En un kernel normal esto se hace con el comando 'nice'. Si nuestro cocinero espera servir más raciones de gambas que de aceitunas haría bien en dedicarle más tiempo a las primeras, lógicamente.
LOS KERNELS RT
El problema de los kernel normales es que las tareas no se pueden interrumpir en cualquier sitio, hay que esperar a que lleguen a ciertos puntos de ejecución donde ya se pueden detener para conmutar a otra. Esto introduce lo que llamamos latencia.
Por ponerlo de una forma simplificada, los kernels rt permiten interrumpir las tareas en más cantidad de sitios que los kernel normales. Pueden hacer, por así decirlo, rodajas más finas de tiempo, así que la tarea actual será desalojada más rápidamente y nuestra tarea prioritaria podrá acceder antes a la CPU. Por lo tanto la latencia será más baja.
Digamos que un kernel rt nos permite dejar una gamba a medio pelar si lo que se necesita en ese momento, urgentemente, es ponerse a deshuesar una aceituna lo antes posible, mientras que en un kernel normal habría que terminar de pelar la gamba.
Además de hacer rodajas más finas, los kernels rt tienen un sistema de prioridades mucho más estricto, donde las tareas prioritarias pegan hachazos inmisericordes a las demás (preempting) para hacerse con el control de la CPU, ralentizando los demás programas lo que sea necesario para cumplir con sus requisitos.
¿CUANDO ES IMPORTANTE UN KERNEL RT?
En dos casos:
1) Cuando necesitamos latencias muy bajas, es decir, reacciones muy rápidas de la máquina. El ejemplo más claro es la ejecución de instrumentos virtuales, donde necesitas que al pulsar una tecla de un teclado MIDI el instrumento suene inmediatamente.
2) Cuando necesitamos prioridades muy estrictas, es decir, que nuestra tarea de alta prioridad no se interrumpa por nada del mundo (a no ser en el caso catastrófico de que la CPU esté tan sobrecargada que se supere el 100% de utilización). Por ejemplo, estamos grabando una sesión de audio con Ardour y observando como suben y bajan los indicadores de los faders. No importa si perdemos algún cuadro de refresco de los faders con tal de que el transporte de sonido del micrófono al disco duro no se vea interrumpido. Un kernel rt ralentizará el refresco de los faders todo lo que sea necesario con tal de que no se pierda ni una muestra de audio.
Dicho esto, en general los kernels no rt más recientes han mejorado mucho su sistema de planificación de tareas y su gestión de prioridades. Si no tienes la CPU al límite de sus posibilidades (digamos por debajo del 50% de utilización) o si no te importa que de vez en cuando se produzca un pequeño microcorte (clic) en el sonido (los tan temidos xruns), un kernel normal da unas prestaciones perfectamente aceptables.
¿QUÉ LATENCIA ES ACONSEJABLE?
A mí personalmente cualquier cosa por debajo de 10 ms ya me va bien y a partir de 20 ms ya empiezo a notar el retardo claramente. Hay gente más exigente. O menos. Como cosa curiosa, los organistas de iglesia son capaces de tocar maravillosamente aún teniendo unas latencias brutales.
Otro día os cuento más sobre configuración del kernel rt.
(c) 2009 Luis Garrido
Este texto se publica bajo una licencia Creative Commons Attribution-Noncommercial-No Derivative