lunes, 24 de abril de 2017

The State of Parallel Programming

En esta entrada escribiré sobre un artículo llamado "The State of Parallel Programming" por UBM TechWeb.

Como es cosumbre, empezaré con la canción de esta entrada, será "No Parallels" por Hands Like Houses.


En mi experiencia como programador, las race conditions y problemas de memoria son similar a los problemas de contaminación de vivir en la Ciudad de México, pasé toda mi tierna infancia sin conocer los riesgos de salud que la contaminación en la Ciudad de México, era feliz, hasta que un día, probablemente durante la pubertad, leí acerca de las contigencias ambientales y como la ciudad es básicamente una enorme cámara de smog, lentamente matándonos.

Probablemente haya exagerado un poco en el párrafo anterior, pero lo necesitaba para argumentar lo siguiente:
Ya que existen varias herramientas que facilitan el desarrollo de aplicaciones multinúcleo, pasé mis primeros días como desarrollador de aplicaciones móviles feliz en la ignorancia de dichos problemas, no me tenía que preocupar por nada ¿consumir servicios web? utilizaré esta función que dice que solo recibe la URL y response con un JSON, en la siguiente línea mandaré los datos a mi tabla con unos 1,000 registros ¿Qué es lo peor que puede pasar? Es más, de una vez aprovecharé para agregar esta librería que dice que maneja efectos visuales cada que una tabla es modificada, se verá bien.

Y por mucho tiempo me salí con la mía, hasta que un día sucedío, mi aplicación crasheaba en momentos irregulares, a veces sin que el usuario clickeara nada, a veces en medio de consumir el servicio web. Probablemente pasé un par de días buscando resolverlo, mejor dicho, pasé los primeros días en negación, seguro es un bug de una de las librerías, no fue hasta que perdí toda la esperanza que investigué y encontré la mismísima caja de Pandora, descubrí sobre el manejo de hilos en aplicaciones móviles, y desde entonces mi vida cambió, pero no forzosamente para bien.

Resultó que todas las librerías que utilizaba requerían llamarse de formas especiales en momentos especiales para poder sincronizarse y no causar crashes random por tratar de leer o modificar un dato que quizá ya no estaba ahí, después no supe nada, solo podía ver un gran hongo radioactivo que representaba todo lo que había estado haciendo mal hasta ese momento explotando en mi cara.

En resumen, descubrí que el hilo central en aplicaciones únicamente es para UI, ¿Servicios web? crea un hiló y ejecútalo de forma asíncrona, cuando termine (si termina) implementa un patrón de observador para que el servicio notifique al UI para que se actualice.

Desde aquel momento mi enfoque al programar cambió drasticamente, paso al menos una sexta parte del tiempo total en que desarrollo aplicaciones revisando que tenga los métodos de sincronización adecuados y otro tercio revisando que no tenga problemas de memoria, pero esa es otra historia.

A eso debo sumar el tiempo que paso leyendo las implementaciones específicas de cada librería que uso, justo hoy tuve un problema con una aplicación legacy que alguien más programó en la empresa que trabajo hace cinco años, alguien que en ese momento aún vivía en su tierna infancia sin race conditions, en resumen, implementó todos los servicios con una función web no asíncrona (y confiaba que no tardara mucho o muriera, porque por supuesto, bloqueaba el hilo central de la aplicación, por cinco bellos años la aplicación funcionó sin muchos problemas, hasta que en la última actualización de sistema operativo Apple decidió que ya no tendría funciones web que soportaran dicha monstruosidad, y en su defecto dejó una función que se llama igual pero a bajo nivel sí es asíncrona y pone un lock en el hilo central para que cosas como la que hizo aquel programador no se rompieran por completo, el problema es que además de ello implementó un mecanismo que crashea la aplicación automáticamente al detectar que un hilo no central trata de modificar el UI, por lo que el código no asíncrono que en algún momento sí se ejecutaba en el hilo central al terminar la función, ahora no lo hacía (aunque el hilo central tuviera un lock),  y por lo tanto, crasheaba la aplicación cada que se consumía un servicio web, todo esto fue de la noche a la mañana. Fue una madrugada divertida.

La razón por la que he decidido contar esta anécdota es porque las gráficas que muestra el artículo plantean un paradigma espantoso para los siguientes años, únicamente 28% de los programadores encuestados no utiliza una herramienta de performance tuning, y aún así, 74% de los programadores no usa o no sabe que herramienta usa para detectar errores de threading, lo cual es curioso, porque al enfocarse en performance sin preocuparse por errores de sincronización muchos desarrolladores pueden caer en el patrón de mandar todo a diferentes hilos en busca de mejorar el performance de su aplicación sin preocuparse por los mecanismos que usara para que la los módulos "paralelizados" sean thread safe, lo peor de todo es que una aplicación que utiliza componentes que no son thread safe puede funcionar por meses, quizá años, hasta que un día algo sucede mal, y todo explota, y dado que el scheduling de los hilos es relativamente aleatorio debuggear aplicaciones con problemas de la sincronización es una de las cosas que te hacen considerar que quizá hubieras sido más feliz cultivando maíz en Matehuala, ¡O HASTA PROGRAMANDO EN LUA!

Las demás gráficas comprueban mi hipótesis, 33% de los programadores encuestados dijeron que considera que se necesita desarrollar más tecnología que determine las secciones de mayor beneficio por paralelizar, pero sólo 21% considera que las tecnologías paralelas deberían evitar el uso incorrecto de paralelización, y solo 8% considera que se necesitan módulos para encontrar defectos, la cosa se pone peor, únicamente un 7% considera que se necesitan librerías que sean thread_safe. Estamos programando nuestra propia tumba. 

Es indispensable entender el concepto de programación concurrente, porque en general, implementar una aplicación concurrente mal programada es peor, por mucho, que implementar una aplicación no concurrente correctamente.

Eso es todo para la entrada de hoy.
Wololo.

No hay comentarios:

Publicar un comentario