miércoles 13 de agosto de 2008

Perjudiciales las interrupciones en las labores humanas

Cuando estás a cargo de un equipo de programadores, una de las primeras cosas que debes aprender a hacer bien es distribuir el trabajo. O lo que es lo mismo darle a las personas qué hacer. Un ejemplo es cuando depositas archivos en sus laps. El cómo decidas cuales archivos depositar en qué laps es una de las áreas donde puedes tener increibles beneficios en cuanto a productividad si lo haces bien. Hazlo mal, y puedes crear una de esas situaciones enmarañadas donde nadie termina algo y todo mundo se queja de que "por aquí nunca se completa nada".

Pongamos sobre la mesa el siguiente problema de programación para tener más claro el tema.

Supón que tienes dos operaciones independientes que ejecutar, A y B. Cada operación requiere 10 segundos de tiempo del CPU. Tienes un CPU el cual, para propósitos de este ejemplo, no tiene nada más en cola.

En nuestro CPU, la multitarea es opcional. Así que puedes hacer estas operaciones una después de la otra...

Procesamiento Secuencial
Operación AOperación B
0102030405060708091011121314151617181920

...ó, empleando multitarea. Si aplicas multitarea, en este CPU en particular, las tareas corren un segundo a la vez, y un cambio entre ellas no toma ningún tiempo.

multitarea
0102030405060708091011121314151617181920

¿Cual elegirias? La reacción de la mayoría de las personas es que la multitarea es lo mejor. En ambos casos, tienes que esperar 20 segundos para obtener ambas respuestas. Sin embargo, piensa sobre cuanto tiempo toma obtener el resultado de cada operación.

En los dos casos, los resultados de la Operación B(mostrado en azul) toman 20 segundos en llegar. Ahora mira la Operación A. Con multitarea, los resultados toman 19 segundos en llegar... cuando con el procesamiento secuencial están listos en solamente 10 segundos.

En otras palabras, en este ejemplo manipulado, el tiempo promedio por operación es menor (15 segundos en lugar de 19.5) cuando usas procesamiento secuencial que cuando usas multitarea. (En realidad, no es un ejemplo manipulado como tal -- fue un problema real que tuvo que ser resuelto en el trabajo)

MétodoOperación A tomóOperación B tomóPromedio
Secuencial10 segundos20 segundos15
Multitarea19 segundos20 segundos19.5

Al principio mencioné que "un cambio entre tareas no toma tiempo." En realidad, en CPUs reales, este cambio toma algo de tiempo... basicamente el tiempo suficiente para guardar el estado de los registros actuales del CPU y cargar los registros de la otra tarea. Realmente, este cambio es imperceptible. Pero para hacerlo más interesante, imaginemos que el cambio toma medio segundo. Ahora las cosas no se ven tan bien:

MétodoOperación A tomóOperación B tomóPromedio
Secuencial10 segundos20 + 1 cambios = 20.5 segundos15.25
Multitarea19 + 18 cambios = 28 segundos20 + 19 cambios = 29.5 segundos28.75

Ahora... se que suena tonto pero ¿que pasaria si cada cambio toma todo un minuto?

MétodoOperación A tomóOperación B tomóPromedio
Secuencial10 segundos20 + 1 cambios = 80 segundos45 segundos
Multitarea19 + 18 cambios = 1099 segundos20 + 19 cambios = 1160 segundos¡Casi 19 Minutos!

A mayor tiempo en el cambio, la multitarea empeora.

Eso no es tan alarmante, o ¿sí?. Habrá quienes digan que esto es estar "contra" la multitarea, es decir, "¿regresar a los días del DOS cuando tenías que salirte de WordPerfect para correr 1-2-3?".

Ese no es el punto. Estarás de acuerdo conmigo en que en este tipo de ejemplo:

  1. en promedio se obtienen resultados más rápidos con el procesamiento secuencial, y
  2. entre más tiempo tome hacer un cambio(de tarea), mayor será la penalización tratándose de multitarea.

Ok, regresando al tema de administrar personas, no CPUs. El problema cuando administras programadores, específicamente, es que el cambio de tareas toma, de veras, de veras, de veras, mucho tiempo. Eso se debe a que programar es la clase de tarea donde tienes que mantener muchas cosas en tu cabeza en ese momento. Entre más cosas recuerdes a la vez, más productivo eres programando. Un programador que trabaja a toda su capacidad está almacenando millones de cosas en su cabeza a la vez: desde nombres de variables, estructuras de datos, APIs importantes, los nombres de las funciones que ya hizo y usa regularmente, inclusive el nombre del directorio donde almacena el código fuente. Si se manda a ese programador de vacaciones tres semanas a Cancún, olvidará todo. Parece que el cerebro humano lo saca de su memoria RAM de corto plazo y lo mueve a una cinta de respaldo que toma una eternidad en cargar.

¿Por cuanto tiempo? bueno, eso depende de cada ambiente de trabajo pero en general cuando te ausentas semanas te toma regularmente varios días ponerte al corriente nuevamente con la dinámica de antes.

A nivel personal -- has notado alguna vez como cuando le asignas a una persona un trabajo hace un muy buen trabajo, pero si le asignas dos trabajos a esa misma persona ¿no termina ni una ni otra?. Hará uno de ellos abandonando el otro, ó hará ambos trabajos pero muy lentos. Ese es el porqué en los trabajos de programación se toma tanto tiempo en cambiar de uno a otro. Cuando tengo dos proyectos de programación al mismo tiempo, alternarlos me toma algo así como 6 horas. Para un día de 8 horas, eso significa que la multitarea reduce mi productividad a 2 horas al día. Bastante triste.

A como se vé, si le das a una persona dos cosas que hacer, deberías agradecerle si trabaja solo en una, porque va a conseguir hacer más cosas y terminarlas antes del tiempo promedio. De hecho, la idea real de todo esto es que nunca deberías permitirle a las personas trabajar en más de una cosa a la vez. Asegurándote de que saben de qué se trata. Los buenos administradores ven sus responsabilidades como el quitar obstáculos para que las personas se puedan enfocar en una sola cosa y lo terminen realmente. Cuando surgen emergencias, vé si las puedes manejar tú antes de delegarlas a un programador que está profundamente concentrado en un proyecto.


Leído en joelonsoftware.com