programming-languages - concurrent programming languages
Multi-Core y Concurrency-Idiomas, Bibliotecas y Técnicas de Desarrollo (16)
El panorama de la arquitectura de la CPU ha cambiado, los núcleos múltiples son una tendencia que cambiará la forma en que debemos desarrollar el software. Realicé el desarrollo de subprocesos múltiples en C, C ++ y Java, hice el desarrollo de procesos múltiples usando varios mecanismos de IPC. Los enfoques tradicionales de usar hilos no parecen facilitar, para el desarrollador, utilizar hardware que soporte un alto grado de concurrencia.
¿De qué idiomas, bibliotecas y técnicas de desarrollo tiene conocimiento que ayuden a aliviar los desafíos tradicionales de crear aplicaciones simultáneas? Obviamente estoy pensando en problemas como estancamientos y condiciones de carrera. Las técnicas de diseño, las bibliotecas, las herramientas, etc. también son interesantes para ayudar a aprovechar y garantizar que se utilicen los recursos disponibles: simplemente escribir una aplicación segura y robusta no asegura que esté utilizando todos los núcleos disponibles.
Lo que he visto hasta ahora es:
- Erlang : proceso basado, mensaje que pasa IPC, el ''modelo de simultaneidad del actor
- Dramatis : biblioteca modelo de actores para Ruby y Python
- Scala : lenguaje de programación funcional para JVM con un poco de soporte de concurrencia agregado
- Clojure : lenguaje de programación funcional para la JVM con una biblioteca de actores
- Termita : un enfoque de proceso del puerto de Erlang y mensaje que pasa al Esquema
¿Qué más sabes, qué te ha funcionado y qué crees que es interesante de ver?
Algunas cosas basadas en Scala:
- PiLib: un lenguaje alojado para la simultaneidad de estilo de cálculo de Pi
- Programación basada en eventos sin inversión de control
- Actores que unifican hilos y eventos
- Scala Multicast Actors: arquitectura e implementación
- Implementando uniones usando emparejamiento de patrones extensible
- Comunicación de objetos de Scala (revisado)
C ++ 0x proporcionará funciones std::lock
para bloquear más de un mutex juntos. Esto ayudará a aliviar el punto muerto debido al bloqueo fuera de orden. Además, la biblioteca de subprocesos C ++ 0x tendrá promesas, futuros y tareas empaquetadas, que permiten que un subproceso espere el resultado de una operación realizada en otro subproceso sin bloqueos de nivel de usuario.
Comencé con .Net Parallel Extensions. Sin embargo, es un CTP y está cambiando en cada nueva relación. Ahora, estoy usando C # con las instancias ThreadPool, BackgroundWorker y Thread. Estoy recodificando algunos procesos críticos en una aplicación de tamaño mediano. No sabía por dónde empezar. Sin embargo, compré la versión para libros electrónicos del libro "C # 2008 and 2005 threaded programming", de Gaston C. Hillar - Packt Publishing - http://www.packtpub.com/beginners-guide-for-C-sharp- 2008-and-2005-threaded-programming / book , hace 7 días. Compré el libro electrónico de los editores, pero ahora el libro está disponible en Amazon.com. Muy recomendado para programadores de C #. Descargué el código y comencé a seguir los ejercicios. El libro es una buena guía con mucho código para practicar. Leí los primeros 6 capítulos. Cuenta historias mientras explica los conceptos más difíciles. Eso es bueno. Es agradable de leer. ¡Pude ver que mi Core 2 Quad Q6700 alcanzaba el 98% de programación de uso de CPU en C # usando 4 hilos concurrentes! Es más fácil de lo que pensaba. Estoy impresionado con los resultados que puedes lograr usando muchos núcleos al mismo tiempo. Recomiendo el libro a aquellos que estén interesados en comenzar con la programación multinúcleo o con hebras usando C #.
Conozco a Reia , un lenguaje que está basado en Erlang pero se parece más a Python / Ruby.
Esta pregunta está estrechamente relacionada con, si no es un duplicado de: ¿Qué modelo de programación paralelo recomienda hoy para aprovechar los procesadores de muchos puntajes del mañana?
Estoy atenta a las extensiones paralelas para .NET y Parallel LINQ .
He estado haciendo programación concurrente en Ada durante casi 20 años.
El lenguaje en sí mismo (no algunos añadidos a la biblioteca) admite el enhebrado ("tareas"), múltiples modelos de programación y múltiples paradigmas de sincronización. Incluso puedes construir tus propios esquemas de sincronización usando las primitivas incorporadas.
Puede pensar en la cita de Ada como una especie de recurso de sincronización orientado a procedimientos, mientras que los objetos protegidos están más orientados a objetos. Rendezvous es similar al viejo concepto CS de monitores , pero mucho más poderoso. Los objetos protegidos son tipos especiales con primitivas de sincronización que le permiten construir cosas exactamente como bloqueos de sistema operativo, semáforos, eventos, etc. Sin embargo, es lo suficientemente potente como para que también pueda inventar y crear sus propios tipos de objetos de sincronización, según sus necesidades exactas .
He usado procesamiento para Python. Simula la API del módulo de subprocesamiento y, por lo tanto, es bastante fácil de usar.
Si usa map/imap
o un generador / lista de comprensión, convertir su código para usar el processing
es sencillo:
def do_something(x):
return x**(x*x)
results = [do_something(n) for n in range(10000)]
se puede paralelizar con
import processing
pool = processing.Pool(processing.cpuCount())
results = pool.map(do_something, range(10000))
que usará cuantos procesadores tenga para calcular los resultados. También hay variantes perezosas ( Pool.imap
) y asincrónicas ( Pool.map_async
).
Hay una clase de cola que implementa Queue.Queue
y los trabajadores que son similares a los hilos.
Gotchas
processing
se basa en fork()
, que debe emularse en Windows. Los objetos se transfieren a través de pickle
/ unpickle
, por lo que debe asegurarse de que esto funcione. Bifurcar un proceso que ya tiene recursos adquiridos puede no ser lo que usted desea (piense en las conexiones a la base de datos), pero en general funciona. Funciona tan bien que se ha agregado a Python 2.6 en la vía rápida (consulte PEP-317 ).
La pregunta ¿Qué modelo de programación paralelo recomienda hoy para aprovechar los procesadores de muchos puntajes del mañana? ya ha sido preguntado. Di la siguiente respuesta allí también.
Kamaelia es un framework Python para construir aplicaciones con muchos procesos de comunicación.
Aquí hay un video de Pycon 2009. Comienza comparando Kamaelia con Twisted y Parallel Python y luego ofrece una demostración práctica de Kamaelia.http://www.kamaelia.org/cat-trans-medium.png Kamaelia - Concurrencia útil, divertida
En Kamaelia construyes sistemas a partir de componentes simples que se comunican entre sí . Esto acelera el desarrollo, ayuda de forma masiva al mantenimiento y también significa que crea software concurrente de forma natural . Está destinado a ser accesible por cualquier desarrollador, incluidos los principiantes. También lo hace divertido :)
¿Qué tipo de sistemas? Servidores de red, clientes, aplicaciones de escritorio, juegos basados en pygame, sistemas y tuberías de transcodificación, sistemas de televisión digital, borradoras de correo no deseado, herramientas de enseñanza, y mucho más :)
Fácil concurrencia con Kamaelia - Parte 1 (59:08)
Fácil concurrencia con Kamaelia - Parte 2 (18:15)
Los bloques de construcción de Threading de Intel para C ++ me parecen muy interesantes. Ofrece un nivel de abstracción mucho más alto que los hilos crudos. O''Reilly tiene un libro muy bueno si te gusta la documentación de árboles muertos. Ver, también, ¿ Alguna experiencia con los bloques de construcción Threading de Intel? .
Sugeriría dos cambios de paradigma:
Memoria transaccional de software
Es posible que desee echar un vistazo al concepto de Software Transactional Memory (STM). La idea es utilizar concurrencia optimista : cualquier operación que se ejecute en paralelo a otras intenta completar su trabajo en una transacción aislada; si en algún momento se ha cometido otra transacción que invalida los datos en los que funciona esta transacción, el trabajo de la transacción se descarta y la transacción se ejecuta nuevamente.
Creo que la primera implementación ampliamente conocida de la idea (si no la prueba de concepto y la primera) es la de Haskell: documentos y presentaciones sobre la memoria transaccional en Haskell . Muchas otras implementaciones se enumeran en el artículo de STM de Wikipedia .
Bucles y promesas de eventos
Otra forma muy diferente de tratar con la concurrencia se implementa en el [lenguaje de programación E] ( http://en.wikipedia.org/wiki/E_(programming_language%29) .
Tenga en cuenta que su forma de lidiar con la concurrencia, así como con otras partes del diseño del lenguaje, se basa en gran medida en el modelo Actor.
Usted mencionó Java, pero solo menciona hilos. ¿Has mirado la biblioteca concurrente de Java? Viene incluido con Java 5 y superior.
Es una biblioteca muy bonita que contiene ThreadPools, CopyOnWriteCollections para nombrar unos pocos. Consulte la documentación en el tutorial de Java . O si lo prefiere, los documentos de Java .
Yo diría:
Modelos: hilos + estado compartido, actores + paso de mensajes, memoria transaccional, mapa / reducir? Idiomas: Erlang, Io, Scala, Clojure, Reia Bibliotecas: Retlang, Jetlang, Kilim, Cilk ++, fork / join, MPI, Kamaelia, Terracota
Mantengo un blog de enlace de concurrencia sobre cosas como esta (Erlang, Scala, enhebrado de Java, modelo de actor, etc.) y pongo un par de enlaces por día:
Java también tiene una biblioteca de actores . ¿Sabías que J ava es un lenguaje funcional? ;)
OpenMP .
Maneja los hilos por usted, de modo que solo se preocupa por las partes de su aplicación C ++ que desea ejecutar en paralelo.
p.ej.
#pragma omp parallel for
for (int i=0; i < SIZE; i++)
{
// do something with an element
}
el código anterior ejecutará el bucle for en tantos subprocesos como le haya indicado al tiempo de ejecución de openmp, de modo que si TAMAÑO es 100 y tiene un cuadro de cuatro núcleos, ese bucle ejecutará 25 elementos en cada núcleo.
Hay algunas otras extensiones paralelas para varios idiomas, pero las que más me interesan son las que se ejecutan en su tarjeta gráfica. Eso es un verdadero procesamiento en paralelo :) (ejemplos: GPU ++ y libSh )
multiprocessing
es una biblioteca de Python que simplifica la programación multi-core, como se menciona en otra respuesta.
El programa escrito con el multiprocessing
de Python puede modificarse fácilmente para enviar trabajo a la nube, en lugar de a los núcleos locales. piCloud se aprovecha de eso para proporcionar una gran capacidad de procesamiento bajo demanda en la nube: solo necesita modificar 2 líneas de su código.
Entonces, aquí está el take-away: al seleccionar una biblioteca para multi-core, uno puede querer preguntar si un enfoque en la nube también tendría sentido.