Microsoft presentó recientemente la nueva versión de su entorno de desarrollo de aplicaciones, Visual Studio 2010. Si el pasado mes les ofrecíamos algunas pinceladas sobre las mejoras en el entorno de programación, complementamos este mes nuestro repaso.

Programación paralela

Desde hace unos años lo más habitual en cualquier ordenador corriente es que disponga de un procesador con al menos dos núcleos. En servidores o máquinas destinadas a tareas más demandantes es muy frecuente que haya varios procesadores con al menos cuatro núcleos. La tendencia es que cada vez haya más núcleos en los procesadores, ya no sólo por rendimiento sino por las ventajas en cuanto a ahorro de energía, temperatura y las limitaciones existentes en cuanto a aumentar la velocidad de frecuencia de reloj. Esto implica que casi cualquier aplicación pueda trabajar en entornos con múltiples núcleos, lo que hace realmente importante sacarle partido a la programación multi-subproceso. El motivo es que anteriormente para aumentar el rendimiento de una aplicación bastaba con moverla a una máquina con un procesador más rápido, sin embargo, hoy en día esto ya no vale, pues el rendimiento se obtiene a través de sacarle partido a más núcleos y no aumentando la velocidad, por los motivos expuestos. Así que si queremos que una aplicación llegue a ser escalable ésta debe sacar partido a múltiples hilos de ejecución y, por lo tanto, a múltiples nodos de procesamiento.

Este tipo de programación paralela siempre ha sido muy compleja, sobre todo a la hora de depurar aplicaciones en las que existen muchas probabilidades de generar interbloqueos o “race conditions”. Con .NET 4.0 y Visual Studio 2010 se incluyen nuevas bibliotecas, tipos y herramientas para facilitar la programación multi-núcleo, y debería ser un área de suma importancia para los programadores.

.NET 4.0 incluye lo que se ha bautizado como “Parallel Extensions” que están formadas por tres nuevos componentes:

- La biblioteca de tareas paralelas (TPL, Task Parallel Library): esta biblioteca dentro del espacio de nombres System.Threading.Taks.Parallel incluye construcciones para ejecutar tareas repetitivas independientes entre sí en paralelo y de forma automática, como por ejemplo versiones paralelas de los bucles For y ForEach.

- El motor de ejecución paralela de Linq (PLINQ Execution Engine): como se desprende de su nombre, se trata de una versión paralelizada de Linq to Objects, que nos permite lanzar consultas integradas en el lenguaje aprovechando la capacidad de paralelismo del sistema.

- Las estructuras de datos para coordinación (CDS, Coordination data Structures): ofrece un conjunto de primitivas de sincronización y de colecciones preparadas para multisubproceso (thread-safe) que simplifican los escenarios paralelizados. Por ejemplo, tenemos diccionarios, pilas y colas thread-safe, y objetos especiales para sincronización de hilos como el SpinWait o el SpinLock.

La MSDN tiene una buena documentación sobre todo esto en: http://msdn.microsoft.com/en-us/library/dd460693.aspx.

Para dar soporte a toda esta tecnología de paralelización, Visual Studio 2010 ofrece también nuevas herramientas de depuración orientadas a conocer el estado de las diversas tareas que se ejecutan en paralelo en cada momento, así como la interacción entre ellas. En concreto disponemos de unos nuevos paneles para ello:

- Panel Parallel Tasks: muestra el listado de hilos activos con los que está trabajando la aplicación, ofreciendo todo tipo de información sobre los mismos, como se observa en la figura 14. La lista va más allá de una mera visión estática ya que es posible hacer doble clic sobre una fila para abrir el código que se está ejecutando y poder inspeccionarlo y depurarlo.

- Panel Parallel Stacks: nos permite obtener una visión sobre lo que está en ejecución en paralelo, organizándolos por hilos o por tareas, ilustrando sus relaciones de manera visual.

- Visualizador de Concurrencia: este panel es mucho más potente y complejo que los dos anteriores. Su objetivo es ver la interacción de los hilos de ejecución ente sí y con el entorno en el que se ejecutan. Dispone de tres vistas para mostrar respectivamente la actividad de las CPU, la interacción entre hilos de la aplicación (para detectar tiempos, bloqueos, carreras…), y la vista de núcleos, que permite ver cómo se mueven nuestras tareas por los diferentes núcleos disponibles a medida que avanza la ejecución. Este visualizador no soporta depuración de aplicaciones Web paralelas.

Novedades en los lenguajes

Junto con la nueva versión de la plataforma .NET también han llegado versiones nuevas de los lenguajes tradicionales de la misma (C#, VB y C++) que ofrecen pequeñas pero interesantes mejoras. Sin embargo, las novedades de calado vienen a través de la inclusión de un nuevo lenguaje de programación funcional F#, y el nuevo soporte para Lenguajes Dinámicos.

La plataforma .Net fue creada originalmente para trabajar con lenguajes de programación fuertemente tipados, como C# y VB, en los que los tipos de datos están predeterminados de antemano y no se pueden cambiar sobre la marcha. Sin embargo, muchos lenguajes para la Web como Ruby, Phyton o JavaScript son lenguajes dinámicos débilmente tipados, que necesitan una dinámica de compilación totalmente diferente ya que en su entorno de trabajo existe un gran desacoplamiento entre las propias aplicaciones y los datos que éstas manejan (sólo hay que pensar en el DOM de una página Web y su naturaleza cambiante y elementos heterogéneos para darse cuenta de ello).

Para poder incorporar lenguajes dinámicos a la plataforma .NET y establecer un puente entre ellos y los lenguajes fuertemente tipados típicos de esta plataforma, .NET 4.0 introduce el Dynamic Language Runtime o DLR, que incluye entre otras las siguientes características:

- Un sistema de tipos dinámicos que permite definir tipos de datos sobre la marcha.

- Generación dinámica de código.

- Caché de resolución de llamadas

- Enlazadores entre lenguajes o binders, que permiten la interacción entre el DLR y otros lenguajes. Así existen binders para objetos .NET, JavaScript en Silverlight, Python, Ruby y COM. Este último ha simplificado mucho el trabajo con código no manejado.

Un gran añadido al arsenal de lenguajes nativos de .NET ha sido F#. Se trata de un lenguaje multi-paradigma que permite utilizar la programación orientada a objetos así como la programación funcional (de ahí su nombre). Nació hace años en los laboratorios de Microsoft Research pero ahora forma parte integral de la plataforma.

La programación funcional es el paradigma de programación más antiguo de todos. Trata los problemas de computación como evaluaciones de funciones, es decir, todo se circunscribe a funciones que toman unos parámetros y devuelven un resultado, sin “efectos secundarios” como cambios en estos parámetros o modificaciones de elementos fuera de la función. Además, no disponen de bucles, sino que usan la recursión para realizar iteraciones. Se basan en la teoría abstracta de las funciones en matemáticas, y permiten usar unas funciones como argumentos de otras así como devolver funciones como resultados. Esto p