Parallel Extensions: del laboratorio a la empresa

No hace mucho, Rodrigo Corral nos comentaba el advenimiento de Parallel Extensions y la importancia que iba a tomar a tomar un tema como la programación concurrente en el futuro próximo.

multicore

Dado que la Ley de Moore no puede continuar sin añadir unidades funcionales extra a los microprocesadores, el paralelismo va a dejar de ser un tema casi exclusivamente circunscrito a la investigación y va a servirse en la gran mesa del desarrollo de soluciones empresariales.

La razón para esto es que ahora las aplicaciones de negocio van a tener que correr en máquinas multi-core, o en máquinas con varios procesadores. Hasta hace pocos años una máquina con varios procesadores estaba prácticamente reservada a la supercomputación, pero hoy en día ya son el pan nuestro de cualquier PC de escritorio e incluso se van a empezar a ver en dispositivos móviles.

La programación concurrente y el paralelismo no son una materia trivial, la sincronización entre procesos no lo es y dividir el trabajo, asignarlo a varios procesadores, recoger los resultados y mezclaros para reconstruir la solución final (Scatter/Gather) tampoco lo es. Mucho se ha trabajado ya en este campo por parte de la comunidad investigadora y existen estrategias (memoria compartida, paso de mensajes), constructos teóricos (locks, semáforos, monitores) y herramientas (OpenMP, MPI, PVM)  que se han ido puliendo durante este tiempo. Cualquiera que haya trabajado con algo de lo anterior sabe bien lo no trivial que es plantear una solución en esos términos y el costo que supone sobre un desarrollo secuencial clásico.

Sin embargo, y como ya comenté en el citado post de Rodrigo, los desarrolladores de negocio no van a tener que lidiar (necesariamente) con esta complejidad, porque sería dar un paso atrás en productividad. Su tarea es seguir dedicando sus esfuerzos a lo que mejor saben hacer, que es desarrollar aplicaciones a alto nivel que resuelven problemas de negocio, no bajar al nivel de ponerse a controlar la ejecución concurrente de sus procesos.

Es aquí donde entra Parallel Extensions, una serie de librerías que vienen incluidas nativamente ya en el .NET Framework 4.0 y que van a permitir al desarrollador de negocio trabajar a alto nivel con la programación concurrente y el paralelismo. Parallels Extensions va a formar parte importante de .NET FX 4.0 (metido hasta la médula en la propia mscorlib.dll) y va a proveer de algunas abstracciones muy interesantes para el desarrollo a alto nivel, como el concepto de Task. A partir de ahora éste debería ser el concepto más usado por desarrolladores de negocio, no el de Thread. Una Task expone una API igual de rica (incluso más) que la de un Thread a la vez que se encarga de dividir el trabajo y lanzar un número óptimo de threads basándose en el número de CPUs o cores que tenemos (evitando el overhead que suponen los cambios de contexto cuando se crean más threads que CPUs disponibles).

Yendo aún más allá, sin llegar al nivel de granularidad de una Task, podemos trabajar a más alto nivel aún con la nueva clase estática Parallel y escribir código tan sorprendente como:

PForEach

Usando un bucle así, y con la salvedad de controlar que una iteración del bucle no dependa de datos compartidos con otra iteración, dejamos que el runtime de Parallel Extensions se encargue de paralelizar el trabajo creando las Tasks y encargándose de todo el proceso. A este nivel, el trabajo con la fontanería del paralelismo casi ha desaparecido.

Los componentes básicos de Parallel Extensions son la Task Parallel Library (TPL), que va a proporcionar las funcionalidades principales mencionadas arriba con las Tasks y la clase Parallel, etc. PLINQ para trabajar con LINQ to Objects en paralelo (y todo lo interesante que suena eso) y el Coordination Data Structures (CDS) que ofrece nuevas primitivas de sincronización, a más alto nivel que las mencionadas antes (semáforos, monitores…).

Todo esto está explicado en detalle y con ejemplos de código funcionando en este video de Channel 9, que recomiendo a cualquiera que le interese este tema.

Parallel Extensions abre unas posibilidades muy interesantes para el futuro próximo, dado el escenario descrito al principio de este post, y dota a .NET de una API muy sencilla para trabajar con temas tan ásperos como la programación concurrente. Habrá que estar atento a su evolución de aquí a la versión final que se incluya en .NET 4.0.

3 comentarios sobre “Parallel Extensions: del laboratorio a la empresa”

  1. Buena recopilación crack.

    En mi opinión, también se trata de un gran paso adelante y, como tal, deberá realizarse de manera sopesada. Esto es, conviene ponerse las pilas en la materia pronto, a nivel didáctico al menos. Ya que a pesar de que las abstracciones que .Net 4.0 u otras plataformas nos ofrezcan, se introducen nuevos factores negativos también, como por ejemplo el indeterminismo que supone confiar en las políticas de asignación de recursos para multiprocesamiento (esto incluye memoria compartida, semáforos, etc).

    Existen algunos proyectos «de laboratorio» como comentas, en este sentido, orientados a mejorar la experiencia del «concurrent debugging», como por ejemplo Maestro, sobre lo cual también podemos encontrar material en Channel 9.

    Cierro mi reflexión con dos frases. La primera, de todos conocida, es que «un gran poder conlleva…», jeje. La segunda, cosecha de un amigo mío, dice que «si los fabricantes de coches quisieran que la gente llevara más cuidado al conducir, los equiparían con machetes en lugar de con airbag». Traducido a nuestro ámbito, creo que podéis imaginar a qué me refiero 🙂

    Veremos cómo evoluciona esta «tendencia».
    Miguel

  2. Como siempre, muy interesanete.

    Mi apunte va referido a si existe también un comportamiento de paralelismo a nivel de SO. Si eso ocurre, la capa de abstracción del uso de la CPU no debería correr a cargo enteramente (o parcialmente) del propio SO? Es en ese nivel donde se podría optimizar el uso de todos los recursos de manera más efeciente, aunque, evidentemente, los algoritmos de predicción/ejecución en paralelo serían muy complicados (o más sencillos pero menos óptimos).

    La cuestión es que si se deja en manos del programador de aplicaciones, de manera exclusiva, el hacer uso de las librerías de paralelismo, muchas de las veces, estaremos añadiendo dificultad/espacio/tiempo en la programación del día a día; es decir, los resultados, probablemente, no serán tan buenos como deberían.

    Deberán los programadores de aplicaciones crearse sus propias capas de paralelismo (por aplicación, por proyecto, por empresa…)?, o se deberá de programar la mejor solución de paralelismo en cada algorismo en concreto?

    Compensa todo este esfuerzo en nuestras habituales aplicaciones de gestión?

    Saludos.

  3. Gracias a todos por los comentarios 🙂

    Creo que de alguna manera se relacionan y plantean cosas muy intereantes.

    Sobre lo que comenta Capitan pir, el objetivo de Parallels es facilitar la labor del desarrollador de negocio, pero no evitar que pueda llegar al grano fino si realmente quiere o necesita llegar a ese nivel de detalle, esa potencia sigue estando ahí. Por otro lado, va a haber herramientas de profiling y debugging específicas en VS2010 para ejecución concurrente (http://msdn.microsoft.com/en-us/concurrency/default.aspx y Channel 9)

    También hay que tener en cuenta, como bien dice Miguel, que el desarrollador debe conocer bien los rudimentos de la programación concurrente, ya que sigue teniendo la llave para que todo esto funcione. No puede desentenderse de estos conceptos porque sigue estando en sus manos crear tareas que sean parelelizables (crear unidades lógicas que puedan computarse por separado garantizando que no habrá race conditions, deadlocks, etc. al paralelizarse…). A nivel conceptual esto tiene que manejarse, otra cosa es tener que hacer a mano toda la fontanería necesaria para poder llevarlo a cabo, aquí es donde entra la ayuda.

    @Daniel, sin conocer a fondo las mejoras en ese campo, sí que es cierto que los SOs han mejorado sus schedulers para optimizar la planificación en paralelo del trabajo que les llega según los recursos de CPU que tengan, pero lo cierto es que el SO actúa a un nivel más bajo: todas las aplicaciones le mandan threads y él los planifica.

    Sin embargo, si una aplicación se hace de manera clásica sencuencial en un sólo thread, nada podrá hacer el scheduler del SO aunque tenga 8 procesadores debajo, ya que sólo hay una tarea que planificar… Por tanto, no se hasta que punto se puede llegar a quitar de las manos del desarrollador completamente el control concurrente.

    De todas maneras, seguro que el paralelismo empieza a calar cada vez más nativamente en los SOs también, al igual que en el desarollo de aplicaciones.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *