viernes, 4 de abril de 2014

This changes everything!

En esta ocasión, leímos el paper denominado Teaching the SIMD Execution Model: Assembling a Few Parallel Programming Skills por Ariel Ortiz, publicado en el marco del 34° SIGCSE, en este se menciona que durante un curso de ensamblador que era ofrecido con anterioridad en el ITESM CEM, era abordado el tema de programación paralela en arquitecturas SIMD (Single instruction/Multiple Data).
Comparación de arquitecturas
Este paper trata un tema bastante interesante, y que jamás había escuchado; a partir de la década de los 90, los procesadores contienen en su arquitectura registros de 64 y 128 bits (dependiendo de su tecnología), lo que se denominó MMX y SSE/2. La verdad es que esto cambia las cosas, ya que permite realizar programación “paralela” en un solo núcleo. ¿Sus desventajas? Hay que programar a bajo nivel, y es posible que algunos compiladores no lo soporten.
Y cuando digo que es necesario programar a bajo nivel, me refiero a que este conjunto de instrucciones SIMD especializadas son aprovechadas en mayor medida al usar… Ensamblador. Aunque existen algunas librerías, como la usada en clase, que permite aprovechar esta capacidad a través de C.
Este modelo de programación paralela mononucleo, que aun puede ser extendida para aprovechar verdaderamente el 100% del potencial de los procesadores modernos, es como sigue:
  1. Cargar diferentes variables (de memoria principal), regularmente de un arreglo, en un registro de 128-bits (el numero de variables dependerá del tamaño de ellas)
  2. Aplicar una operación a los dos registros de 128-bits, el resultado será un registro de 128-bits (donde las variables individuales que representan resultados independientes).
  3. Si es necesario, cargar de nuevo el valor a memoria principal (separando de nuevo las variables)

Como podemos ver, estas operaciones son mas útiles cuando queremos aplicar una misma operación a diferentes variables (dentro de un arreglo), por ejemplo, sumarle “dos” a cada registro. De esta forma (y dependiendo del tamaño de las variables), podemos modificar concurrentemente 4, 8, 16, etc. registros en una sola operación a nivel procesador.

Por esta razón, esta técnica tiene un uso más extendido en procesamiento audiovisual, grafico, matemático, y compresión donde el tiempo es vital.

martes, 25 de marzo de 2014

MapReduce: paradigma de hoy

En los últimos años mucha personas han tratado de dar solución al problema de procesamiento de grandes cantidades de datos (Big Data), pues este representa un problema practico en el que es necesario analizar toda esta información en un tiempo razonable. Muchos esfuerzos se han hecho para tratar de  solucionar este problema (e.g. supercomputadoras, paradigmas de multiprocesamiento, etc.), sin embargo, una de las soluciones más efectivas (gracias a la escalabilidad y costos) es el uso del computo distribuido.
El computo paralelo ha evolucionado a través del tiempo, y mientras que sus bases, la distribución de las operaciones lógica y de entrada-salida a través de procesadores y/o equipos, muchos paradigmas se ha explorado, pero el problema del sincronizado de datos a través de diferentes nodos ha continuado. Recientemente, un nuevo paradigma, el map-reduce, ha sido adoptado y evolucionado hasta convertirse en el indicado para compañías donde sus procesos están muy relacionados con el procesamiento extensivo de datos, como Google, Microsoft, y Amazon.
El paradigma de Map-reduce utiliza el concepto de map y reduce incluidos en los lenguajes derivados de LISP, que procesan independientemente datasets con el fin de producto nuevas instancias de estos, pero as pequeños. Básicamente, la idea es procesar datos en una función map, previamente definida por el usuario donde la información es indexada y procesada, y enviada a una función reduce, que también esta definida por el usuario, de tal forma que “agregue” las tuplas resultantes previamente procesadas de tal forma que estas sean presentadas de una forma útil al ser post-procesadas.

La ventaja de usar este nuevo paradigma es que la información puede ser dividida en diferentes datasets, procesados independientemente, y reducidos posteriormente en una función reduce especializada. Esto provee una alternativa para reducir costos al usar grandes clústeres formados de computadoras domesticas (de conveniencia) que podían superar a las grandes computadoras comerciales al ser comparadas en su relación desempeño/costo, además de proveer una infraestructura muy robusta, tolerante a fallas, en la que las optimizaciones correctas a una computadora maestra, que asigna los nodos que ejecutaran tareas de map y reduce, puede sencillamente reemplazar y/o compensar la falla de una computadora gracias al poder de la grid que maneja, proveyendo un clúster confiable compuesto de maquinas sencillas y que en si mismas no son confiables.

viernes, 7 de marzo de 2014

Teaching Concurrency-Oriented Programming with Erlang

En esta ocasión, leímos el paper escrito por nuestro profesor de programación multinúcleo, Ariel Ortiz, el cual fue publicado en el contexto del SIGCSE’11. En este articulo se trata principalmente la enseñanza de programación concurrente utilizando el modelo de pase de mensajes (message-passing) de Erlang.
Adicionalmente, podemos explorar de nuevo las principales características de las lecturas que hemos hecho acerca de la importancia de la programación concurrente al aprovechar plenamente los nuevos modelos de arquitectura computacional o la distribución de tareas a través de diversos equipos a través de la red.
Un apartado que me pareció especialmente importante es To Mutate, Or To Not Mutate, donde se exploran las principales debilidades del modelo concurrente en lenguajes diseñados bajo el paradigma procedural u orientado a objetos, ya que hace énfasis en que la raíz de todos los problemas de sincronización surge básicamente al permitir la mutación de estados, y obviamente la falta de atomicidad de los cambios, sin embargo, al reducir las variables a estados no mutables, o finales, se reduce considerablemente la complejidad de las implementaciones concurrentes.
El uso de Erlang para implementación de algoritmos u sistemas concurrentes me parece interesante, ya que permite una implementación un poco mas transparente de los algoritmos desde su fase de planeación y producción, del lado del desarrollador, sin embargo, me parece que su API es algo limitado, además de un poco diferente a lo que los demás lenguajes funcionales (y naturalmente los procedurales) nos tienen acostumbrados.  Por lo que creo que prefiero (al menos por ahora) un lenguaje como Clojure, que implementa un API mucho mas extenso e inherentemente seguro en lo concurrente.

Para concluir, creo que lo que me parecería interesante, y espero ver en el futuro, seria un lenguaje naturalmente paralelo que además implemente alguna forma de objetos, para poder encapsular funcionalidades.

viernes, 21 de febrero de 2014

Indie Game

Esta semana vimos el documental Indie Game: The movie, que si bien no se relaciona directamente con la materia de programación multinúcleo, presenta casos reales de desarrolladores que lograron cumplir sus sueños a través de su propio esfuerzo y dedicación.
El documental explora el desarrollo de diferentes videojuegos encargados por sus equipos, que muchas veces estaban conformados por 2 o 3 personas, como Super Meat Boy, Fez y Braid. A pesar de ser grupos pequeños, se puede ver la gran necesidad de tener un control, organización y planeación de sus responsabilidades para llegar a un fin en común.
En lo general, yo no soy un gamer en todo sentido de la palabra, ya que si juego algunos títulos pero me aburro rápido y me pongo a hacer tras cosas, sin embargo, el desarrollo de videojuegos siempre me ha parecido interesante desde el punto de vista técnico, ya que estos requieren de la combinación correcta de programación, para hacer las cosas realidad, diseño para hacerlo estético y usable de forma natural, redacción para hacer una historia interesante y liderazgo para organizar y planear las diferentes etapas del desarrollo.
Personalmente, creo que este documental trata una temática muy interesante e importante en la carrera, ya que muestra la forma de dedicación correcta del desarrollador que logra grandes proyectos. Ya que muestra que la pasión y ganas de hacer las cosas es mas importante que ganar dinero de tus actividades, y que si tienes un sueño es posible realizarlo aunque tengan recursos limitados.
La verdad es que la película muestra una realidad cruda donde podemos ver el estrés real que se sufre al realizar lanzamientos masivos, donde los errores inesperados son siempre presentes y que no es lo mas inteligente realizar cambios de ultima hora en proyectos grandes ya que se desestabiliza el producto.

martes, 11 de febrero de 2014

Welcome to this wild world...

En esta ocasión leímos Welcome to the Jungle de Herb Sutter, continuación del articulo The Free Lunch Is Over del mismo autor que discutimos hace un par de semanas, en este se discute acerca de la adopción de dispositivos con capacidades en Hardware que permiten la implementación y uso correcto de técnicas de concurrencia.
En el 2005 la industria comenzó a incluir dispositivos que utilizaban hardware paralelo (en su mayoría multicore) en sus catálogos de productos, y en tan solo 6 años, en el 2011, lograron completar una importante, y significativa transición en los equipos de sobremesa y portátiles.
Esta revolución nos dejó en una situación en la que hay una gran variedad de dispositivos, tecnologías, y enfoques que aprovechan la concurrencia de alguna u otra forma, nos menciona, obviamente, los procesadores multi-core (ya cubiertos en el articulo citado), el uso de núcleos o unidades de procesamiento especializados (como los GPUs), uso de modelos elásticos (HaaS).
Creo que el autor nos presenta una visión bastante objetiva y acertada acerca de la situación del software en el mundo, ya que a pesar de que la transición ha sido casi transparente para el usuario, el mundo de desarrollo ha sufrido bastantes revoluciones y cambios de corriente de pensamiento en los últimos 30 años. Pasando desde programación meramente procedural, a la de objetos, y esta al descubrimiento de la mejora teoría exponencial del procesamiento, después a concurrencia, y ahora a varios caminos, donde la forma de programar se ha visto muy afectada.
Una cosa que me parece muy importante es la razón de por que todos estos cambios han pasado de manera tan apresurada y abrupta. Creo que las primeras dos revoluciones (programación procedural y orientada a objetos) son simples evoluciones y perfeccionamientos de la técnica de la programación, situaciones que se dan muy a menudo en toda ciencia, pero, las ultimas revoluciones sufridas vienen como consecuencia de la sobreexplotación de La Ley de Moore, que el autor describe como una mina de oro, que comienza rica y donde la extracción es extremadamente barata, y parece que así seguirá (pero toda ley exponencial debe terminar en la practica), la “ambición” de los mineros los llevo a la perfección de circuitos y uso de los transistores para producir mejoras en threads sencillos, y eventualmente a crear múltiples cores usado otra “vena de la mina”, pero la mina sigue agotándose y al decantarse por utilizar la tercera y mas cara de ellas han decidido apostar por múltiples arquitecturas.

lunes, 3 de febrero de 2014

Distribuye y vencerás

En esta ocasión leímos el articulo Parallel Computing on any desktop de Ami Marowka, que fue publicado por la revista Communications of the ACM en Septiembre del 2007; en este articulo nos expone una perspectiva de la evolución de la computación paralela hasta esos momentos.

Marowka retoma algunos de los puntos que ya hemos tratado a lo largo del curso, y este blog. Pero haciendo mas énfasis en la implementación practica y económica de este modelo de programación, expone que antiguamente (en la década pasada apenas) era muy costoso obtener equipo que soportara estas practicas, y que solo organizaciones millonarias y universidades de prestigio apoyadas con inversores podían darse el lujo de adquirirlas, hasta que entraron al mercado los Beowulf clústeres, arreglos de computadoras domesticas administradas por software que las hacia trabajar como un conjunto en una tarea especifica, que permitían comprar poco a poco el paralelismo necesario y proveían una escalabilidad casi lineal.

Debo decir que cuando leí este articulo, estaba bastante confundido, pues exponía el uso de arreglos de computadoras como solución al manejo de paralelismo en tareas complejas o mejor dicho CPU bound (que requieren uso intensivo de CPU), cuando este articulo hablaba de programación paralela, y no de computo distribuido, que es el concepto bajo el cual yo conocía estas soluciones (uso de commodity PCs en una tarea en particular colaborativamente); y por esto, me dediqué a investigar en que momento mi entendimiento de la diferencia entre estas dos técnicas falló, según un moderador del StackExchange de Computer Science, la diferencia radica en que el computo distribuido es un subconjunto de las técnicas de paralelización, ya que estas simplemente se enfocan en ejecutar tareas en diferentes procesadores, ya sea que estos compartan el mismo CPU, motherboard, o inclusive caché.

El articulo habla también de la necesidad de que los desarrolladores en común adopten las nuevas tecnologías disponibles para ayudar a paralelizar sus programas, uno de los ejemplos de librerías concurrentes que expone es OpenMP, ya que con pocas líneas de código encima del código ya escrito es posible paralelizar bloques de código iterativos como for, y while.
Gilles. (2012, Abril 29). Computer science stackexchange: Re [Online forum comment]. Extraido de http://cs.stackexchange.com/a/1582

viernes, 24 de enero de 2014

Opinión acerca de la situación actual en multiprocesamiento

Esta semana leímos The Free Lunch Is Over: A Fundamental Turn Toward Concurrency in Software escrito por Herb Sutter, además de algunos otros textos referentes a los antecedentes de la programación multinúcleo, la arquitectura planeada y las problemáticas asociadas.
Tendencias de crecimiento
Este texto, presenta además, la perspectiva desde el punto de vista del desarrollador y las necesidades inherentes de la industria. Se comenta que hace alrededor de dos décadas los desarrolladores de software gozaban de la ventaja de que sus algoritmos medianamente optimizados en algún momento serian ejecutables de forma aparentemente inmediata o razonablemente en tiempo desde el punto de vista de un usuario que cambiara su equipo de computo reciente mente, ya que aprovecharía los avances nuevos de las productoras de microprocesadores que hasta la fecha cumplen con la Ley de Moore, sin embargo, hay ciertas limitantes.

El texto presenta diversos puntos y posturas muy interesantes que definitivamente lo hacen un articulo esencial para una gran población de los profesionales de TI, sin embargo, me dedicaré únicamente a comentar algunos puntos que me parecen relevantes:

  • Dependencia dura del performance de una aplicación: la opinión generalmente aceptada por el publico es que entre mas velocidad de reloj mejor performance tendremos, y si bien es un punto importante, hay que considerar el numero de núcleos, caché, y optimizaciones a nivel de instrucciones maquina, elementos que deberíamos considerar al comparar equipos de computo, al menos sobre papel; sobretodo el caché que muchas veces pasa desapercibido
    • El texto menciona que los desarrolladores de las nuevas generaciones de procesadores tienen mucha presión en desarrollar procesadores cada vez mas rápidos, al punto que han decidido implementar “reordenación” de instrucciones de I/O, cuestión que se me hizo por demás interesante, ya que a pesar de tener contacto con diferentes lenguajes, y personas con diferentes experiencias y usos de estos jamás, he oído de problemas asociados a esto, algo que me parece muy interesante, ya que no creo que sean cuestiones fáciles de implementar.
  • Dependencia “suave” del performance de una aplicación: muchas veces no pensamos en esta parte, cosa que ha dado como resultado programadores que no se preocupan por la optimización de sus soluciones, lo cual, por otro lado podría incrementar los costos de desarrollo pero que bien lo valen. Este punto, es precisamente el central de nuestra futura discusión a lo largo del semestre, pues se requieren desarrollos que implementen esta técnica “esotérica” con mucho mas frecuencia hasta que se vuelva un estándar.
    • Las computadoras actuales desaprovechan los recursos ya que las aplicaciones no están hechas para correr de forma correcta en ellas, echando a la basura en realidad nuestra inversión económica al tratar de mejorar nuestra experiencia general (overall experience) del día a día.
    • Pienso que la habilidad de un programador de crear soluciones concurrentes en problemas medianamente paralelizables será un factor discriminante en el mediano plazo para determinar empleos, y la calidad inmanente en el software, lo que podría diferenciar claramente a los hobbistas y a los profesionales del sector, diferenciación que actualmente se esta volviendo borrosa con la publicación de frameworks cada vez mas sencillos y amigables, por otro lado afectará positivamente en cuan valioso será un desarrollador profesional frente a un hobbista en la industria especializada, sin embargo, podría afectar negativamente a los aspirantes a las carreras relacionadas, que de por si serán escasos según lo proyectado por diversos estudios.
  • Soporte nativo de paralelismo: la lectura indica que diversos lenguajes modernos han decidido implementar mecanismos nativos para el manejo de concurrencia y sus posibles complicaciones (condición de carrera, comunicación, sincronización, etc.), sin embargo, muchos lenguajes populares no cuentan con estos mecanismos, o no los han estandarizado para ser compilados para diversas plataformas a partir del mismo código fuente.
    • Creo que los lenguajes como C/C++ deben aportar estos mecanismos, pero estos también deben ser apoyados por los diseñadores de sistemas operativos, pues creo que los avances realmente significativos se darán cuando los lenguajes puedan interactuar de forma nativa, directa y segura con los sistema de scheduling propios de cada sistema operativo, pues actualmente es una lucha de estira y afloja entre los desarrolladores como usuarios finales, los lenguajes, el sistema operativo esencial, y la optimización forzada dada en los procesadores modernos.
En conclusión, creo que el mundo del software esta experimentando una de las revoluciones mas importantes de su historia, una revolución que aumentara la complejidad lógica al diseñar e implementar soluciones, pero que no necesariamente debería decepcionar a la gente antes de probar las nuevas practicas, pues estás son necesarias, y pronto, serán naturales. También, es importante notar el estado de la industria del hardware hoy en día, donde probablemente en apariencia un equipo con 2 cores podrá superar a un equipo con 4 cores (a la mitad de procesamiento) si el código a correr no esta optimizado, o si las diversas variables como el tamaño del cache, latencia de la memoria principal y discos duros, no son tomadas en cuenta, ya que todo suma, donde los últimos mencionados podrían hacer parecer que el performance incrementa o disminuya exponencialmente.