set_start_method parallelism parallel new from parallel-processing distributed multicore multiprocessing mpi

parallel-processing - parallelism - python new process



MPI para multinĂșcleo (7)

Con el reciente alboroto en la programación multinúcleo, ¿alguien está explorando las posibilidades de usar MPI ?


MPI no es ineficiente. Debe dividir el problema en pedazos y pasar los trozos y reorganizar cuando el resultado finalice por porción. Nadie en el buen sentido pasaría por todo el objeto a través de MPI cuando solo se está trabajando en una porción del problema por hilo. No es la ineficiencia de la interfaz o el patrón de diseño esa es la ineficiencia del conocimiento de los programadores sobre cómo resolver un problema.

Cuando usa un mecanismo de bloqueo, la sobrecarga del mutex no se escala bien. esto se debe al hecho de que la secuencia de ejecución subrayada no sabe cuándo va a bloquear el siguiente subproceso. Realizará más batido de nivel de núcleo utilizando mutex que un patrón de diseño de paso de mensaje.


MPI tiene una gran cantidad de gastos generales, principalmente para manejar la comunicación entre procesos y sistemas heterogéneos. Lo he usado en casos donde se está pasando una pequeña cantidad de datos, y donde la relación de computación a datos es grande. Este no es el escenario de uso típico para la mayoría de las tareas de consumo o comerciales, y en cualquier caso, como se mencionó en una respuesta anterior, en una arquitectura de memoria compartida como una máquina multinúcleo, existen formas mucho más rápidas de manejarlo, como los punteros de memoria.

Si tiene algún tipo de problema con las propiedades descritas anteriormente, y desea distribuir el trabajo a otras máquinas, que deben estar en la misma red de alta velocidad que usted, entonces quizás MPI tenga sentido. Sin embargo, me cuesta imaginar ese escenario.


No, en mi opinión, no es adecuado para la mayoría del procesamiento que haría en un sistema multinúcleo. La sobrecarga es demasiado alta, los objetos que pasas deben estar profundamente clonados, y pasar grandes objetos por los gráficos para luego ejecutar un cómputo muy pequeño es muy ineficiente. En realidad, está diseñado para compartir datos entre procesos separados, la mayoría de las veces se ejecuta en espacios de memoria separados y, en la mayoría de los casos, se ejecutan cómputos largos.
Un procesador multinúcleo es una máquina de memoria compartida, por lo que existen formas mucho más eficientes de hacer el procesamiento en paralelo, que no implica copiar objetos y donde la mayoría de los hilos se ejecutan durante un tiempo muy corto. Por ejemplo, piense en un Quicksort multiproceso. La sobrecarga de asignar memoria y copiar los datos a un hilo antes de que pueda ser particionada será mucho más lenta con MPI y un número ilimitado de procesadores que el Quicksort ejecutándose en un único procesador.
Como ejemplo, en Java, usaría un BlockingQueue (una construcción de memoria compartida), para pasar referencias de objetos entre hilos, con muy poca sobrecarga.
No es que no tenga su lugar, por ejemplo, el grupo de búsqueda de Google que utiliza el envío de mensajes. Pero probablemente no es el problema que estás tratando de resolver.


Personalmente he tomado Erlang (y me gusta hasta ahora). El enfoque basado en mensajes parece ajustarse a la mayor parte del problema y creo que será uno de los elementos clave para la programación multinúcleo. Nunca supe sobre los gastos generales de MPI y gracias por señalarlo


Tendría que estar de acuerdo con tgamblin. Probablemente tendrás que arremangarte y realmente profundizar en el código para usar MPI, manejando explícitamente la organización del mensaje. Si este es el tipo de cosa que te gusta o no te molesta hacer, esperaría que MPI funcionara tan bien en máquinas multinúcleo como lo haría en un clúster distribuido.

Hablando desde mi experiencia personal ... codifiqué un código C en la escuela de postgrado para hacer algunos modelos a gran escala de modelos electrofisiológicos en un clúster donde cada nodo era una máquina multinúcleo. Por lo tanto, había un par de métodos paralelos diferentes en los que pensé para abordar el problema.

1) Podría usar MPI solo, tratando cada procesador como si fuera su propio "nodo", aunque algunos de ellos estén agrupados en la misma máquina.

2) Podría usar MPI para manejar datos que se mueven entre nodos multinúcleo, y luego usar subprocesos (subprocesos POSIX) dentro de cada máquina multinúcleo, donde los procesadores comparten memoria.

Para el problema matemático específico en el que estaba trabajando, primero probé dos formulaciones en una sola máquina multinúcleo: una que usaba MPI y otra que usaba hilos POSIX. Resultó que la implementación de MPI era mucho más eficiente, lo que da una aceleración de cerca de 2 para una máquina de doble núcleo en comparación con 1.3-1.4 para la implementación con hilos. Para el código MPI, pude organizar las operaciones de modo que los procesadores rara vez estaban inactivos, manteniéndose ocupados mientras se transmitían los mensajes entre ellos y enmascarando gran parte de la demora en la transferencia de datos. Con el código enhebrado, terminé con muchos cuellos de botella mutex que obligaban a los subprocesos a sentarse y esperar mientras que otros subprocesos completaban sus cálculos. Mantener la carga computacional balanceada entre hilos no pareció ayudar a este hecho.

Esto puede haber sido específico solo para los modelos en los que estaba trabajando, y la efectividad del enhebrado frente al MPI probablemente variaría enormemente para otros tipos de problemas paralelos. Sin embargo, no estoy de acuerdo con que MPI tenga una sobrecarga inmanejable.


He usado MPI extensivamente en clusters grandes con nodos multi-core. No estoy seguro si es lo correcto para una sola caja multi-core, pero si anticipa que su código algún día puede escalar más que un solo chip, podría considerar implementarlo en MPI. En este momento, nada escalas más grande que MPI. No estoy seguro de dónde provienen los carteles que mencionan los gastos indirectos inaceptables, pero traté de dar una visión general de las compensaciones relevantes a continuación. Sigue leyendo para más información.

MPI es el estándar de facto para el cálculo científico a gran escala y ya se usa ampliamente en máquinas multinúcleo. Es muy rápido. Echa un vistazo a la lista de los Top 500 más recientes . Las máquinas más importantes de esa lista tienen, en algunos casos, cientos de miles de procesadores, con nodos de doble y doble núcleo multitarjeta. Muchas de estas máquinas tienen redes personalizadas muy rápidas (Torus, Mesh, Tree, etc.) e implementaciones optimizadas de MPI que conocen el hardware.

Si desea usar MPI con una máquina de múltiples núcleos de un solo chip, funcionará bien. De hecho, las versiones recientes de Mac OS X vienen con OpenMPI preinstalado, y usted puede descargar OpenMPI de una instalación sin problemas en una máquina Linux común de múltiples núcleos. OpenMPI está en uso en Los Alamos en la mayoría de sus sistemas. Livermore usa mvapich en sus clusters de Linux. Lo que debe tener en cuenta antes de sumergirse es que MPI fue diseñado para resolver problemas científicos a gran escala en sistemas de memoria distribuida . Los cuadros de múltiples núcleos con los que está tratando probablemente tengan memoria compartida .

OpenMPI y otras implementaciones usan la memoria compartida para el paso de mensajes local de forma predeterminada, por lo que no tiene que preocuparse por la sobrecarga de red cuando transfiere mensajes a procesos locales. Es bastante transparente, y no estoy seguro de dónde otros carteles están recibiendo sus inquietudes sobre los gastos generales. La advertencia es que MPI no es la cosa más fácil que puede utilizar para obtener el paralelismo en una sola caja de múltiples núcleos. En MPI, todo el mensaje que pasa es explícito. Se lo ha llamado el "lenguaje ensamblador" de la programación paralela por este motivo. La comunicación explícita entre procesos no es fácil si usted no es una persona con experiencia en HPC , y existen otros paradigmas más adecuados para la memoria compartida ( UPC , OpenMP y buenos lenguajes como Erlang, por nombrar algunos) que podría probar primero.

Mi consejo es ir con MPI si prevé escribir una aplicación paralela que puede necesitar más de una sola máquina para resolver. Podrás probar y ejecutar correctamente con un cuadro de varios núcleos, y la migración a un clúster será bastante fácil una vez que lo hagas funcionar allí. Si está escribiendo una aplicación que solo necesitará una sola máquina, intente con otra cosa. Hay formas más fáciles de explotar ese tipo de paralelismo.

Finalmente, si te sientes realmente aventurero, prueba MPI junto con hilos, OpenMP o algún otro paradigma local de memoria compartida. Puede usar MPI para el paso de mensajes distribuidos y algo más para el paralelismo en el nodo. Aquí es donde van las grandes máquinas; se espera que las futuras máquinas con cientos de miles de procesadores o más tengan implementaciones de MPI que se escalen a todos los nodos pero no a todos los núcleos, y las personas de HPC se verán obligadas a crear aplicaciones híbridas. Esto no es para los débiles de corazón, y hay mucho trabajo por hacer antes de que haya un paradigma aceptado en este espacio.


Debe decidir si desea subprocesos de bajo nivel o subprocesos de alto nivel. Si quieres un nivel bajo, utiliza pThread. Tienes que tener cuidado de no introducir condiciones de carrera y hacer que el rendimiento del subprocesamiento trabaje en tu contra.

He utilizado algunos paquetes OSS para (C y C ++) que son escalables y optimizo la programación de tareas. TBB (threading building blocks) y Cilk Plus son buenos y fáciles de codificar y obtener aplicaciones de la tierra. También creo que son lo suficientemente flexibles como para integrar otras tecnologías de hilos en un momento posterior si es necesario (OpenMP, etc.)

www.threadingbuildingblocks.org www.cilkplus.org