4 de mayo de 2007

Dynticks

Ya he escrito sobre esto, pero como me han pedido que escriba sobre ello y lo que ya escribí sobre el tema era una mierda, lo vuelvo a contar.

Dynticks es una novedad que ha aparecido en Linux 2.6.21. Dynticks tiene que ver con la esencia de la multitarea y de los mecanismos que permiten que un sistema operativo moderno pueda ejecutar varios procesos simultaneamente sin que ninguno de ellos sea capaz de monopolizar la CPU y afectar a la estabilidad global del sistema.

Para entender que es dynticks, hay que entender la multitarea y hay que entender esos mecanismos. La multitarea se inventó hace décadas, concretamente en la década de los 60. En los grandes superordenadores de aquel tiempo se iban almacenando procesos en la memoria pero se ejecutaba solamente, desde que empezaba hasta que acababa. Con el tiempo la gente se dió cuenta que cuando un proceso utilizaba ciertos tipos de dispositivos de entrada/salida que eran muy lentos -una impresora, por ejemplo- el programa se pasaba mucho tiempo esperando a que el dispositivo terminara esa operación. Asi que construyeron sistemas en los que cuando un proceso se ponía a esperar a un dispositivo, se guardaba el estado del proceso y se ejecutaba otro que hubiera rondando por memoria. Esto permitía utilizar la CPU al 100% y no desaprovechar la máquina, que era lo que se buscaba. Sin embargo, no permitía interactividad: Un proceso podía perfectamente no utilizar ningún dispositivo de E/S y estar horas ejecutándose sin dejar ejecutarse a otro proceso. Esto al principio estuvo bien, pero luego la necesidad -que es la madre de todo buen software- y los usuarios pijos hicieron que varios usuarios quisieran tener acceso a la máquina simultaneamente sin tener que esperar a ningún proceso. Asi surgió la multitarea cooperativa, en la que los procesos cedían a menudo su turno en el procesador para poder dar la impresión de que todos los procesos se ejecutaban a la vez. Sin embargo, este sistema era frágil y evolucionó rápidamente en la multitarea apropiativa (preemptive).

La multitarea apropiativa consigue que ningún proceso pueda monopolizar la CPU. El mecanismo consiste en un temporizador que activa una interrupción periódicamente. Esa interrupción tiene más prioridad que ninguna otra. Cuando esa interrupción se activa, se guarda el estado del proceso, y se procede a ejecutar una rutina de código situado en uh lugar de la memoria que el sistema operativo debe haber especificado al arrancar. Esa rutina es el gestor de procesos, y su labor es decidir qué proceso debe continuar ejecutándose: el mismo u otro. Si no hay nada que hacer, simplemente llama a un trozo de código que consiste en un bucle infinito que es cuando se dice que el procesador no está haciendo nada. El temporizador volverá a ejecutarse, interrumpirá ese bucle, y vuelta a empezar. Aparte de todo esto están las interrupciones tradicionales: ratón, teclado, tarjeta de red, disco, etc; cuando se produce una de esas interrupciones tambien se para lo que se esté haciendo, en ese mismo instante, y se pasa a atender la interrupción. Pero eso no interesa demasiado ahora, puesto que el punto de vista que debemos mantener ahora es el de la CPU y el temporizador.

Esa es la base de todo sistema operativo moderno y es lo que hacen Linux, NT, OS X. ¿Cual es el problema de este sistema? Solo uno: Hoy en día, y especialmente en los dispositivos portátiles, es importante ahorrar energía. Por eso todos los procesadores modernos tienen, desde hace muchos años, una instrucción especial apodada HLT para ese "bucle infinito" en el que no se hace nada, y que está optimizada para ahorrar energía en la circuitería del procesador. Sin embargo, esto no es suficiente en cuanto a ahorro de energía. En los últimos años se han añadido modos de ahorro de energía que ahorran más energía que la ejecución en bucle de esa instrucción. El modo de ahorro de energía es activado por el sistema operativo cuando no hay nada que hacer, el procesador se pone en modo de ahorro de energía, y cuando la interrupción del temporizador llega el procesador "despierta" de ese modo y ejecuta el código del gestor de procesos. Estos modos son los llamados C-states, CPU-states, estados de la CPU. A día de hoy esto se gestiona mediante ACPI, y con estos modos el universo se ha redefinido para que todo sea un estado: El estado C0 es el estado normal en el que el procesador ejecuta instrucciones de un prpograma, el C1 es cuando se ejecuta la instrucción HLT, y el C2 y el C3 son los modos de ahorro de energía adicionales que se activan, por ejemplo, entre pulsación y pulsación de tecla en el word. Pero estos modos tienen un problema: Cuanto más "profundo" sea el modo de ahorro de energía, más latencia tarda en despertar el procesador de ese modo. Esto es debido a que los modos de ahorro de energía desactivan partes de la circuitería del procesador y se tarda algo de tiempo en volver a activarlas. Y significa que ese modo de ahorro de energía te cuesta rendimiento: Para volver a ponerte a ejecutar instrucciones porque, por ejemplo, llega una interrupción provocada por la llegada de un paquete a la tarjeta de red, tienes que sufrir una penalización adicional.

Pero esto no es todo. Aun con estos modos de ahorro de energía, hay que "despertar" el procesador para algo tan simple como una pulsación de teclado, puestos que son modos que solamente pueden activarse a la hora de "no hacer nada". Es más, aun si tienes algun programa utilizando aunque solamente sea un 20% del procesador -un programa de descarga P2P, por ejemplo-, tienes que salir de esos modos de ahorro de energía muy a menudo y ponerte a ejecutar sus instrucciones con la caldera del procesador consumiendo energía a tope. Para solucionar esos problemas en los últimos años tambien se han añadido los P-states, Performance-states, estados de rendimiento que consisten en reducir la frecuencia de funcionamiento del procesador para poder disminuir el consumo del procesador y de ese modo ahorrar energía; a costa, por supuesto, de rendimiento (para entenderlo mejor, podría apodarselo underclocking dinámico). La idea consiste en que si no estás utilizando el procesador al 100% y tan solo estás utilizando por ejemplo un 20-30%, puedes disminuir la frecuencia del reloj y empeorar el rendimiento del procesador. De ese modo, tu programa utilizará más % de CPU, pero lo hara consumiendo menos energía (aunque sea durante más tiempo) y consumirá aun menos cuando no lo esté utilizando. Así, un Via C7-M 795 puede pasar de consumir 20 W a 2 GHz, a consumir tan solo 5, funcionando a 400 MHz. Los estados del procesador C2 y similares, por supuesto, se siguen aplicando, aunque siguen ahorrando la misma energía, ellos van aparte del escalado de frecuencias. Todos esto lo llega a percibir el usuario en su portátil en esos selectores que le permiten escoger entre optimizar para consumo y optimizar para el rendimiento: Según lo que el usuario elija o dependiendo de si está conectado a un adaptador o tira de batería, el sistema operativo cambiará de unos modos a otros.

Una vez puesto todo esto sobre la mesa, tan solo queda hablar de Dynticks. Dynticks no cambia nada a como funciona los mecanismos de la multitarea, pero las explota de una manera que los sistemas operativos de propósito general no lo habían hecho nunca. En vez de ejecutar programar el temporizador a una frecuencia fija (1000 veces por segundo en Linux 2.6, 100 en Linux 2.4, 100 o 100 y pico en XP) y ejecutar un bucle con la instrucción HLT cuando el sistema no tiene nada que hacer, el kernel mira primero la lista de temporizadores que los procesos del sistema tienen de forma directa o indirecta en el kernel, y busca el más próximo. Si el más próximo no va a necesitar ser atendido hasta dentro de, pongamos, un segundo (una barbaridad para un procesador); el kernel programa el temporizador del kernel no para dentro de 1/1000 segundos,que es la frecuencia fija que se suele utilizar, sino para dentro de un segundo. Esto significa que el procesador podrá pasarse -si una interrupción de un dispositivo no se cruza en su camino- todo un segundo en el estado C2/C3; algo que no puede hacer normalmente, puesto que está forzado a despertarse del modo C-state cada vez que el temporizador se "despierta". Y esto ahorra más energía, claro. En un sistema con dynticks activado, el número de interrupciones por segundo pasa de 1000/s (lo mínimo que se puede llegar a tener con el temporizador programado a despertarse 1000 veces por segundo) a 1-2 por segundo; estando sin hacer nada, claro.

Dynticks ha tenido además un efecto secundario beneficioso en el mundo de la virtualización: Puesto que un sistema real sin dynticks llama al temporizador 1000 (en linux) veces por segundo, cuando es virtualizado necesita que el huesped virtualize esas 1000 interrupciones por segundo. Si le añades varias CPUs virtuales a un huesped que tenga un solo procesador te encontrarás con que tan solo sin estar haciendo nada, la gestión de esas interrupciones del temporizador come mucha CPU del huesped. Con dynticks, al reducirse el ritmo de interrupciones por segundo cuando no se hace nada, el huesped se ahorra CPU, lo cual le permite tambien ahorrar energía, sobre todo si el huesped tambien utiliza dynticks.

6 comentarios:

  1. Gracias por el aumento de la explicación. Lo he leido una vez, no me he enterado de nada. Soy realmente muy nuevo en esto de la informática, pero tambien un martillo cuando me da por algo, y cuando hay buena información es más fácil.

    Repito las gracias y ya volveré a darle una segunda lectura.

    ResponderEliminar
  2. Gran entrada, mis felicitaciones.



    PS - Hay que motivarte, a ver si conseguimos así más grandes comentarios sobre el kernel y menos de Perez-Reverte ;)

    ResponderEliminar
  3. Con esta clase de genialidades me dan ganas de llorar, que buen articulo.

    ¿Existe algun presedente a Dynticks?

    Gracias

    ResponderEliminar
  4. Dios
    es precedente
    perdon

    ResponderEliminar
  5. Grandísimo artículo. Merece que añada el blog a mi Google Reader.

    ResponderEliminar
  6. Wow, si en el principio existió la multitarea, y ahora Dynticks, mi mente empieza de nuevo a soñar con lo que vendrá en el futuro, un gran invento/diseño para los tiempos donde todo se hace cada vez mas portatil.

    ResponderEliminar