stringtranslate.com

Interfaz de paso de mensajes

La interfaz de paso de mensajes ( MPI ) es un estándar de paso de mensajes estandarizado y portátil diseñado para funcionar en arquitecturas de computación paralela . [1] El estándar MPI define la sintaxis y la semántica de rutinas de biblioteca que son útiles para una amplia gama de usuarios que escriben programas de paso de mensajes portátiles en C , C++ y Fortran . Existen varias implementaciones de MPI de código abierto , que fomentaron el desarrollo de una industria de software paralelo y alentaron el desarrollo de aplicaciones paralelas a gran escala portátiles y escalables.

Historia

El esfuerzo por desarrollar una interfaz de paso de mensajes comenzó en el verano de 1991, cuando un pequeño grupo de investigadores inició un debate en un retiro de montaña en Austria. De ese debate surgió un Taller sobre estándares para el paso de mensajes en un entorno de memoria distribuida, que se celebró el 29 y 30 de abril de 1992 en Williamsburg, Virginia . [2] Los asistentes a Williamsburg discutieron las características básicas esenciales para una interfaz de paso de mensajes estándar y establecieron un grupo de trabajo para continuar el proceso de estandarización. Jack Dongarra , Tony Hey y David W. Walker presentaron una propuesta preliminar, "MPI1", en noviembre de 1992. En noviembre de 1992, se celebró una reunión del grupo de trabajo MPI en Minneapolis y se decidió dar un carácter más formal al proceso de estandarización. El grupo de trabajo MPI se reunió cada 6 semanas durante los primeros 9 meses de 1993. El borrador del estándar MPI se presentó en la conferencia Supercomputing '93 en noviembre de 1993. [3] Después de un período de comentarios públicos, que dieron como resultado algunos cambios en MPI, la versión 1.0 de MPI se lanzó en junio de 1994. Estas reuniones y la discusión por correo electrónico constituyeron en conjunto el Foro MPI, cuya membresía ha estado abierta a todos los miembros de la comunidad de computación de alto rendimiento .

En el proyecto MPI participaron unas 80 personas de 40 organizaciones, principalmente de Estados Unidos y Europa. La mayoría de los principales proveedores de computadoras concurrentes participaron en el proyecto MPI, colaborando con investigadores de universidades, laboratorios gubernamentales y la industria .

MPI proporciona a los proveedores de hardware paralelo un conjunto de rutinas claramente definido que se pueden implementar de manera eficiente. Como resultado, los proveedores de hardware pueden basarse en esta colección de rutinas estándar de bajo nivel para crear rutinas de nivel superior para el entorno de comunicación de memoria distribuida que se proporciona con sus máquinas paralelas . MPI proporciona una interfaz portátil fácil de usar para el usuario básico, pero lo suficientemente potente como para permitir que los programadores utilicen las operaciones de paso de mensajes de alto rendimiento disponibles en las máquinas avanzadas.

En un esfuerzo por crear un estándar universal para el paso de mensajes, los investigadores no lo basaron en un único sistema, sino que incorporaron las características más útiles de varios sistemas, incluidos los diseñados por IBM, Intel , nCUBE , PVM, Express, P4 y PARMACS. El paradigma de paso de mensajes es atractivo debido a su amplia portabilidad y se puede utilizar en la comunicación para multiprocesadores de memoria distribuida y memoria compartida, redes de estaciones de trabajo y una combinación de estos elementos. El paradigma se puede aplicar en múltiples entornos, independientemente de la velocidad de la red o la arquitectura de la memoria.

Las reuniones del MPI recibieron apoyo en parte de la DARPA y de la Fundación Nacional de Ciencias de Estados Unidos (NSF) en virtud de la subvención ASC-9310330, el acuerdo de cooperación del Centro de Ciencia y Tecnología de la NSF número CCR-8809615, y de la Comisión Europea a través del Proyecto Esprit P6643. La Universidad de Tennessee también realizó contribuciones financieras al Foro MPI.

Descripción general

MPI es un protocolo de comunicación para programar [4] computadoras paralelas . Se admiten tanto comunicaciones punto a punto como colectivas. MPI "es una interfaz de programación de aplicaciones de paso de mensajes, junto con especificaciones de protocolo y semánticas sobre cómo deben comportarse sus características en cualquier implementación". [5] Los objetivos de MPI son el alto rendimiento, la escalabilidad y la portabilidad. MPI sigue siendo el modelo dominante utilizado en la informática de alto rendimiento en la actualidad. [6]

MPI no está aprobado por ningún organismo de normalización importante; sin embargo, se ha convertido en un estándar de facto para la comunicación entre procesos que modelan un programa paralelo que se ejecuta en un sistema de memoria distribuida . Las supercomputadoras de memoria distribuida reales, como los clústeres de computadoras, a menudo ejecutan dichos programas.

El modelo principal MPI-1 no tiene un concepto de memoria compartida , y MPI-2 tiene solo un concepto limitado de memoria compartida distribuida . No obstante, los programas MPI se ejecutan regularmente en computadoras con memoria compartida, y tanto MPICH como Open MPI pueden usar memoria compartida para la transferencia de mensajes si está disponible. [7] [8] El diseño de programas en torno al modelo MPI (al contrario de los modelos explícitos de memoria compartida ) tiene ventajas cuando se ejecuta en arquitecturas NUMA , ya que MPI fomenta la localidad de memoria . La programación explícita de memoria compartida se introdujo en MPI-3. [9] [10] [11]

Aunque MPI pertenece a las capas 5 y superiores del Modelo de Referencia OSI , las implementaciones pueden cubrir la mayoría de las capas, con sockets y el Protocolo de Control de Transmisión (TCP) utilizados en la capa de transporte.

La mayoría de las implementaciones de MPI consisten en un conjunto específico de rutinas directamente invocables desde C , C++ , Fortran (es decir, una API) y cualquier lenguaje capaz de interactuar con dichas bibliotecas, incluyendo C# , Java o Python . Las ventajas de MPI sobre las bibliotecas de paso de mensajes más antiguas son la portabilidad (porque MPI se ha implementado para casi todas las arquitecturas de memoria distribuida) y la velocidad (porque cada implementación está, en principio, optimizada para el hardware en el que se ejecuta).

MPI utiliza especificaciones independientes del lenguaje (LIS) para llamadas y enlaces de lenguaje. El primer estándar MPI especificó enlaces ANSI C y Fortran-77 junto con el LIS. El borrador se presentó en Supercomputing 1994 (noviembre de 1994) [12] y se finalizó poco después. Alrededor de 128 funciones constituyen el estándar MPI-1.3 que se publicó como el final de la serie MPI-1 en 2008. [13]

En la actualidad, el estándar tiene varias versiones: la versión 1.3 (comúnmente abreviada MPI-1 ), que enfatiza el paso de mensajes y tiene un entorno de ejecución estático, MPI-2.2 (MPI-2), que incluye nuevas características como E/S paralelas, administración de procesos dinámicos y operaciones de memoria remota, [14] y MPI-3.1 (MPI-3), que incluye extensiones a las operaciones colectivas con versiones no bloqueantes y extensiones a las operaciones unilaterales. [15] El LIS de MPI-2 especifica más de 500 funciones y proporciona enlaces de lenguaje para ISO C , ISO C++ y Fortran 90. También se agregó interoperabilidad de objetos para permitir una programación más sencilla de paso de mensajes en lenguaje mixto. Un efecto secundario de la estandarización de MPI-2, completada en 1996, fue clarificar el estándar MPI-1, creando el MPI-1.2.

MPI-2 es en su mayor parte un superconjunto de MPI-1, aunque algunas funciones han quedado obsoletas. Los programas MPI-1.3 aún funcionan con implementaciones MPI compatibles con el estándar MPI-2.

MPI-3.0 introduce actualizaciones significativas al estándar MPI, incluidas versiones no bloqueantes de operaciones colectivas, mejoras en operaciones unilaterales y un enlace Fortran 2008. Elimina enlaces C++ obsoletos y varias rutinas y objetos obsoletos. Es importante destacar que cualquier programa MPI-2.2 válido que evite los elementos eliminados también es válido en MPI-3.0.

MPI-3.1 es una actualización menor enfocada en correcciones y aclaraciones, particularmente para los enlaces Fortran. Introduce nuevas funciones para manipular valores MPI_Aint, rutinas de E/S colectivas sin bloqueo y métodos para recuperar valores de índice por nombre para variables de rendimiento MPI_T. Además, se agregó un índice general. Todos los programas MPI-3.0 válidos también son válidos en MPI-3.1.

MPI-4.0 es una actualización importante que incorpora versiones de gran cantidad de rutinas, operaciones colectivas persistentes, comunicaciones particionadas y un nuevo método de inicialización de MPI. También agrega afirmaciones de información de la aplicación y mejora las definiciones de manejo de errores, junto con varias mejoras menores. Cualquier programa MPI-3.1 válido es compatible con MPI-4.0.

MPI-4.1 es una actualización menor enfocada en correcciones y aclaraciones al estándar MPI-4.0. Deja obsoletas varias rutinas, la clave de atributo MPI_HOST y el archivo de inclusión Fortran mpif.h. Se ha agregado una nueva rutina para consultar sobre el hardware que ejecuta el programa MPI. Cualquier programa MPI-4.0 válido sigue siendo válido en MPI-4.1.

A menudo se compara a MPI con Parallel Virtual Machine (PVM), que es un popular entorno distribuido y sistema de paso de mensajes desarrollado en 1989, y que fue uno de los sistemas que motivó la necesidad de un paso de mensajes paralelo estándar. Los modelos de programación de memoria compartida con subprocesos (como Pthreads y OpenMP ) y la programación de paso de mensajes (MPI/PVM) pueden considerarse complementarios y se han utilizado juntos en ocasiones, por ejemplo, en servidores con múltiples nodos grandes de memoria compartida.

Funcionalidad

La interfaz MPI está diseñada para proporcionar topología virtual esencial, sincronización y funcionalidad de comunicación entre un conjunto de procesos (que se han asignado a nodos/servidores/instancias de computadora) de una manera independiente del lenguaje, con sintaxis específica del lenguaje (vinculaciones), más algunas características específicas del lenguaje. Los programas MPI siempre funcionan con procesos, pero los programadores comúnmente se refieren a los procesos como procesadores. Por lo general, para obtener el máximo rendimiento, a cada CPU (o núcleo en una máquina multinúcleo) se le asignará un solo proceso. Esta asignación ocurre en tiempo de ejecución a través del agente que inicia el programa MPI, normalmente llamado mpirun o mpiexec.

Las funciones de la biblioteca MPI incluyen, entre otras, operaciones de envío/recepción de tipo rendezvous punto a punto, elección entre una topología de proceso lógico cartesiano o de tipo gráfico , intercambio de datos entre pares de procesos (operaciones de envío/recepción), combinación de resultados parciales de cálculos (operaciones de recopilación y reducción), sincronización de nodos (operación de barrera), así como obtención de información relacionada con la red, como la cantidad de procesos en la sesión de computación, la identidad del procesador actual al que está asignado un proceso, los procesos vecinos accesibles en una topología lógica, etc. Las operaciones punto a punto vienen en formas sincrónicas , asincrónicas , con búfer y listas , para permitir semánticas relativamente más fuertes y más débiles para los aspectos de sincronización de un envío de rendezvous. Muchas operaciones destacadas [ aclaración necesaria ] son ​​posibles en modo asincrónico, en la mayoría de las implementaciones.

Tanto MPI-1 como MPI-2 permiten implementaciones que superponen la comunicación y el cálculo, pero la práctica y la teoría difieren. MPI también especifica interfaces seguras para subprocesos , que tienen estrategias de cohesión y acoplamiento que ayudan a evitar estados ocultos dentro de la interfaz. Es relativamente fácil escribir código MPI punto a punto multiproceso, y algunas implementaciones admiten dicho código. La comunicación colectiva multiproceso se logra mejor con múltiples copias de comunicadores, como se describe a continuación.

Conceptos

MPI ofrece varias funciones. Los siguientes conceptos brindan contexto para todas esas capacidades y ayudan al programador a decidir qué funcionalidad utilizar en sus programas de aplicación. Cuatro de los ocho conceptos básicos de MPI son exclusivos de MPI-2.

Comunicador

Los objetos comunicadores conectan grupos de procesos en la sesión MPI. Cada comunicador le da a cada proceso contenido un identificador independiente y organiza sus procesos contenidos en una topología ordenada . MPI también tiene grupos explícitos, pero estos son principalmente buenos para organizar y reorganizar grupos de procesos antes de que se cree otro comunicador. MPI comprende operaciones intracomunicadores de un solo grupo y comunicación bilateral entre comunicadores. En MPI-1, las operaciones de un solo grupo son las más frecuentes. Las operaciones bilaterales aparecen principalmente en MPI-2, donde incluyen comunicación colectiva y gestión dinámica en proceso.

Los comunicadores se pueden particionar mediante varios comandos MPI. Estos comandos incluyen MPI_COMM_SPLIT, donde cada proceso se une a uno de varios subcomunicadores de color al declarar que tiene ese color.

Conceptos básicos de punto a punto

Varias funciones MPI importantes implican la comunicación entre dos procesos específicos. Un ejemplo popular es MPI_Send, que permite que un proceso específico envíe un mensaje a un segundo proceso específico. Las operaciones punto a punto, como se las llama, son particularmente útiles en la comunicación con patrones o irregulares, por ejemplo, una arquitectura de datos en paralelo en la que cada procesador intercambia rutinariamente regiones de datos con otros procesadores específicos entre los pasos de cálculo, o una arquitectura maestro-esclavo en la que el maestro envía nuevos datos de tarea a un esclavo cada vez que se completa la tarea anterior.

MPI-1 especifica mecanismos para mecanismos de comunicación punto a punto tanto bloqueantes como no bloqueantes, así como el llamado mecanismo "listo para enviar" mediante el cual se puede realizar una solicitud de envío solo cuando ya se ha realizado la solicitud de recepción correspondiente.

Fundamentos colectivos

Las funciones colectivas implican la comunicación entre todos los procesos de un grupo de procesos (que puede significar todo el conjunto de procesos o un subconjunto definido por el programa). Una función típica es la MPI_Bcastllamada (abreviatura de " difusión "). Esta función toma datos de un nodo y los envía a todos los procesos del grupo de procesos. Una operación inversa es la MPI_Reducellamada, que toma datos de todos los procesos de un grupo, realiza una operación (como sumar) y almacena los resultados en un nodo. MPI_ReduceSuele ser útil al principio o al final de un cálculo distribuido grande, donde cada procesador opera sobre una parte de los datos y luego los combina para obtener un resultado.

Otras operaciones realizan tareas más sofisticadas, como por MPI_Alltoallejemplo reorganizar n elementos de datos de modo que el n- ésimo nodo obtenga el n -ésimo elemento de datos de cada uno.

Tipos de datos derivados

Muchas funciones MPI requieren que se especifique el tipo de datos que se envían entre procesos. Esto se debe a que MPI tiene como objetivo brindar soporte a entornos heterogéneos donde los tipos pueden representarse de manera diferente en los diferentes nodos [16] (por ejemplo, pueden estar ejecutando diferentes arquitecturas de CPU que tienen diferente orden de bytes ), en cuyo caso las implementaciones MPI pueden realizar la conversión de datos . [16] Dado que el lenguaje C no permite que un tipo en sí mismo se pase como parámetro, MPI predefine las constantes MPI_INT, MPI_CHAR, MPI_DOUBLEpara que se correspondan con int, char, double, etc.

He aquí un ejemplo en C que pasa matrices de ints desde todos los procesos a uno. El proceso que recibe se llama proceso "raíz" y puede ser cualquier proceso designado, pero normalmente será el proceso 0. Todos los procesos piden enviar sus matrices a la raíz con MPI_Gather, lo que equivale a que cada proceso (incluido el propio proceso raíz) llame MPI_Sendy el proceso raíz realice la cantidad correspondiente de MPI_Recvllamadas ordenadas para ensamblar todas estas matrices en una más grande: [17]

int enviar_matriz [ 100 ]; int raíz = 0 ; /* o lo que sea */ int num_procs , * recv_matriz ; MPI_Comm_size ( comm , & num_procs ); recv_matriz = malloc ( num_procs * sizeof ( enviar_matriz )) ; MPI_Gather ( enviar_matriz , sizeof ( enviar_matriz ) / sizeof ( * enviar_matriz ), MPI_INT , recv_matriz , sizeof ( enviar_matriz ) / sizeof ( * enviar_matriz ), MPI_INT , raíz , comm );                       

Sin embargo, es posible que desee enviar datos como un bloque en lugar de 100 ints. Para ello, defina un tipo de datos derivado de "bloque contiguo":

MPI_Datatype nuevo tipo ; MPI_Type_contiguous ( 100 , MPI_INT , y nuevo tipo ); MPI_Type_commit ( y nuevo tipo ); MPI_Gather ( matriz , 1 , nuevo tipo , recepción_matriz , 1 , nuevo tipo , raíz , comm );          

Para pasar una clase o una estructura de datos, MPI_Type_create_structcrea un tipo de datos derivado de MPI a partir de MPI_predefinedtipos de datos, de la siguiente manera:

int MPI_Type_create_struct ( int recuento , int * longitud de bloque , MPI_Aint * disp , MPI_Datatype * tipo , MPI_Datatype * nuevo tipo )          

dónde:

La dispmatriz (desplazamientos) es necesaria para la alineación de la estructura de datos , ya que el compilador puede rellenar las variables en una clase o estructura de datos. La forma más segura de encontrar la distancia entre diferentes campos es obtener sus direcciones en la memoria. Esto se hace con MPI_Get_address, que normalmente es lo mismo que &el operador de C, pero eso podría no ser cierto cuando se trabaja con la segmentación de la memoria . [18]

Pasar una estructura de datos como un bloque es significativamente más rápido que pasar un elemento a la vez, especialmente si la operación debe repetirse. Esto se debe a que los bloques de tamaño fijo no requieren serialización durante la transferencia. [19]

Dadas las siguientes estructuras de datos:

estructura A { int f ; corto p ; };      estructura B { estructura A a ; int pp , vp ; };        

Aquí está el código C para crear un tipo de datos derivado de MPI:

estática constante int blocklen [] = { 1 , 1 , 1 , 1 }; estática constante MPI_Aint disp [ ] = { offsetof ( estructura B , a ) + offsetof ( estructura A , f ), offsetof ( estructura B , a ) + offsetof ( estructura A , p ), offsetof ( estructura B , pp ), offsetof ( estructura B , vp ) }; estática MPI_Datatype tipo [] = { MPI_INT , MPI_SHORT , MPI_INT , MPI_INT }; MPI_Datatype nuevotipo ; MPI_Type_create_struct ( sizeof ( tipo ) / sizeof ( * tipo ), blocklen , disp , tipo , & nuevotipo ); MPI_Type_commit ( & nuevotipo );                                               

Conceptos del MPI-2

Comunicación unilateral

MPI-2 define tres operaciones de comunicación unilaterales, MPI_Put, MPI_Get, y MPI_Accumulate, que son una escritura en la memoria remota, una lectura desde la memoria remota y una operación de reducción en la misma memoria a lo largo de varias tareas, respectivamente. También se definen tres métodos diferentes para sincronizar esta comunicación (bloqueos globales, por pares y remotos), ya que la especificación no garantiza que estas operaciones se hayan realizado hasta un punto de sincronización.

Estos tipos de llamadas a menudo pueden ser útiles para algoritmos en los que la sincronización sería inconveniente (por ejemplo, la multiplicación de matrices distribuidas ) o cuando es deseable que las tareas puedan equilibrar su carga mientras otros procesadores están operando con datos.

Gestión dinámica de procesos

El aspecto clave es "la capacidad de un proceso MPI de participar en la creación de nuevos procesos MPI o de establecer comunicación con procesos MPI que se han iniciado por separado". La especificación MPI-2 describe tres interfaces principales mediante las cuales los procesos MPI pueden establecer comunicaciones dinámicamente, MPI_Comm_spawn, MPI_Comm_accept/ MPI_Comm_connecty MPI_Comm_join. La MPI_Comm_spawninterfaz permite que un proceso MPI genere una serie de instancias del proceso MPI nombrado. El conjunto de procesos MPI recién generado forma un nuevo MPI_COMM_WORLDintracomunicador pero puede comunicarse con el padre y el intercomunicador que devuelve la función. MPI_Comm_spawn_multiplees una interfaz alternativa que permite que las diferentes instancias generadas sean binarios diferentes con argumentos diferentes. [20]

E/S

La característica de E/S paralela a veces se denomina MPI-IO, [21] y se refiere a un conjunto de funciones diseñadas para abstraer la gestión de E/S en sistemas distribuidos a MPI y permitir que se pueda acceder fácilmente a los archivos de manera estructurada utilizando la funcionalidad de tipo de datos derivado existente.

La poca investigación que se ha hecho sobre esta característica indica que puede no ser trivial obtener ganancias de alto rendimiento mediante el uso de MPI-IO. Por ejemplo, una implementación de multiplicaciones de matriz-vector dispersas utilizando la biblioteca MPI I/O muestra un comportamiento general de ganancia de rendimiento menor, pero estos resultados no son concluyentes. [22] No fue hasta que se implementó la idea de E/S colectiva [23] en MPI-IO que MPI-IO comenzó a alcanzar una adopción generalizada. La E/S colectiva aumenta sustancialmente el ancho de banda de E/S de las aplicaciones al hacer que los procesos transformen colectivamente las operaciones de E/S pequeñas y no contiguas en operaciones grandes y contiguas, reduciendo así el bloqueo y la sobrecarga de búsqueda de disco. Debido a sus grandes beneficios de rendimiento, MPI-IO también se convirtió en la capa de E/S subyacente para muchas bibliotecas de E/S de última generación, como HDF5 y Parallel NetCDF . Su popularidad también desencadenó la investigación sobre optimizaciones de E/S colectivas, como la E/S consciente del diseño [24] y la agregación entre archivos. [25] [26]

Implementaciones oficiales

Muchos otros esfuerzos son derivados de MPICH, LAM y otros trabajos, incluidas, entre otras, las implementaciones comerciales de HPE , Intel , Microsoft y NEC .

Si bien las especificaciones exigen una interfaz en C y Fortran, el lenguaje utilizado para implementar MPI no está limitado a coincidir con el lenguaje o los lenguajes que busca soportar en tiempo de ejecución. La mayoría de las implementaciones combinan C, C++ y lenguaje ensamblador, y están dirigidas a programadores de C, C++ y Fortran. Hay enlaces disponibles para muchos otros lenguajes, incluidos Perl, Python, R, Ruby, Java y CL (consulte #Enlaces de lenguaje).

La ABI de las implementaciones de MPI se divide aproximadamente entre MPICH y los derivados de Open MPI , de modo que una biblioteca de una familia funciona como un reemplazo directo de una de la misma familia, pero el reemplazo directo entre familias es imposible. La CEA francesa mantiene una interfaz de contenedor para facilitar dichos cambios. [27]

Hardware

La investigación de hardware MPI se centra en la implementación de MPI directamente en el hardware, por ejemplo, a través de un procesador en memoria , incorporando operaciones MPI en los microcircuitos de los chips de RAM en cada nodo. Por implicación, este enfoque es independiente del lenguaje, el sistema operativo y la CPU, pero no se puede actualizar ni eliminar fácilmente.

Otro enfoque ha sido agregar aceleración de hardware a una o más partes de la operación, incluido el procesamiento de hardware de colas MPI y el uso de RDMA para transferir datos directamente entre la memoria y el controlador de interfaz de red sin intervención de la CPU o del núcleo del sistema operativo.

Envoltorios del compilador

mpicc (y de manera similar mpic++ , mpif90 , etc.) es un programa que envuelve un compilador existente para establecer los indicadores de línea de comandos necesarios al compilar código que utiliza MPI. Por lo general, agrega algunos indicadores que permiten que el código se compile y se vincule con la biblioteca MPI. [28]

Enlaces de idioma

Los enlaces son bibliotecas que extienden el soporte de MPI a otros lenguajes al envolver una implementación de MPI existente, como MPICH o Open MPI.

Infraestructura lingüística común

Las dos implementaciones administradas de Common Language Infrastructure .NET son Pure Mpi.NET [29] y MPI.NET [30] , un esfuerzo de investigación de la Universidad de Indiana con licencia de estilo BSD . Es compatible con Mono y puede hacer un uso completo de las estructuras de red MPI de baja latencia subyacentes.

Java

Aunque Java no tiene un enlace MPI oficial, varios grupos intentan unir ambos, con distintos grados de éxito y compatibilidad. Uno de los primeros intentos fue mpiJava de Bryan Carpenter, [31] esencialmente un conjunto de envoltorios de interfaz nativa de Java (JNI) para una biblioteca MPI de C local, lo que da como resultado una implementación híbrida con portabilidad limitada, que también debe compilarse contra la biblioteca MPI específica que se esté utilizando.

Sin embargo, este proyecto original también definió la API mpiJava [32] (una API MPI de facto para Java que seguía de cerca los enlaces equivalentes de C++) que otros proyectos MPI de Java posteriores adoptaron. Una API menos utilizada es la API MPJ, que fue diseñada para estar más orientada a objetos y más cerca de las convenciones de codificación de Sun Microsystems . [33] Más allá de la API, las bibliotecas MPI de Java pueden depender de una biblioteca MPI local o implementar las funciones de paso de mensajes en Java, mientras que algunas como P2P-MPI también proporcionan funcionalidad peer-to-peer y permiten el funcionamiento en plataformas mixtas.

Algunas de las partes más desafiantes de Java/MPI surgen de características de Java como la falta de punteros explícitos y el espacio de direcciones de memoria lineal para sus objetos, que hacen que la transferencia de matrices multidimensionales y objetos complejos sea ineficiente. Las soluciones alternativas generalmente implican transferir una línea a la vez y/o realizar una deserialización y conversión explícitas tanto en el extremo de envío como en el de recepción, simular matrices de tipo C o Fortran mediante el uso de una matriz unidimensional y punteros a tipos primitivos mediante el uso de matrices de un solo elemento, lo que da como resultado estilos de programación bastante alejados de las convenciones de Java.

Otro sistema de paso de mensajes Java es MPJ Express. [34] Las versiones recientes se pueden ejecutar en configuraciones de clúster y multinúcleo. En la configuración de clúster, puede ejecutar aplicaciones Java paralelas en clústeres y nubes. Aquí, los sockets Java o las interconexiones de E/S especializadas como Myrinet pueden admitir la mensajería entre procesos MPJ Express. También puede utilizar la implementación nativa de C de MPI utilizando su dispositivo nativo. En la configuración multinúcleo, se ejecuta una aplicación Java paralela en procesadores multinúcleo. En este modo, los procesos MPJ Express están representados por subprocesos Java.

Julia

Existe un contenedor de lenguaje Julia para MPI. [35]

MATLAB

Existen algunas implementaciones académicas de MPI que utilizan MATLAB . MATLAB tiene su propia biblioteca de extensión paralela implementada utilizando MPI y PVM .

OCaml

El módulo OCamlMPI [36] implementa un gran subconjunto de funciones MPI y se utiliza activamente en computación científica. Se "MPIificó" un programa OCaml de 11.000 líneas utilizando el módulo, con 500 líneas adicionales de código y una ligera reestructuración, y se ejecutó con excelentes resultados en hasta 170 nodos en una supercomputadora. [37]

PARI/GP

PARI/GP se puede construir [38] para utilizar MPI como su motor multihilo, lo que permite ejecutar programas PARI y GP en paralelo en clústeres MPI sin modificaciones.

Pitón

Los contenedores MPI mantenidos activamente para Python incluyen: mpi4py, [39] numba-mpi [40] y numba-jax. [41]

Los desarrollos discontinuados incluyen: pyMPI , pypar, [42] MYMPI [43] y el submódulo MPI en ScientificPython .

R

Los enlaces R de MPI incluyen Rmpi ​​[44] y pbdMPI [45] , donde Rmpi ​​se centra en el paralelismo entre administradores y trabajadores , mientras que pbdMPI se centra en el paralelismo SPMD . Ambas implementaciones son totalmente compatibles con Open MPI o MPICH2 .

Programa de ejemplo

Aquí hay un programa "¡Hola, mundo!" en MPI escrito en C. En este ejemplo, enviamos un mensaje de "hola" a cada procesador, lo manipulamos de manera trivial, devolvemos los resultados al proceso principal e imprimimos los mensajes.

/*  Programa de prueba MPI "Hola mundo" */ #include <assert.h> #include <stdio.h> #include <string.h> #include <mpi.h>    int principal ( int argc , char ** argv ) { char buf [ 256 ]; int mi_rango , num_procs ;          /* Inicializar la infraestructura necesaria para la comunicación */ MPI_Init ( & argc , & argv );   /* Identificar este proceso */ MPI_Comm_rank ( MPI_COMM_WORLD , & my_rank );   /* Descubra cuántos procesos totales están activos */ MPI_Comm_size ( MPI_COMM_WORLD , & num_procs );   /* Hasta este punto, todos los programas han estado haciendo exactamente lo mismo.  Aquí, verificamos el rango para distinguir los roles de los programas */ if ( my_rank == 0 ) { int other_rank ; printf ( "Tenemos %i procesos. \n " , num_procs );          /* Enviar mensajes a todos los demás procesos */ for ( other_rank = 1 ; other_rank < num_procs ; other_rank ++ ) { sprintf ( buf , "Hola %i!" , other_rank ); MPI_Send ( buf , 256 , MPI_CHAR , other_rank , 0 , MPI_COMM_WORLD ); }                    /* Recibir mensajes de todos los demás procesos */ for ( other_rank = 1 ; other_rank < num_procs ; other_rank ++ ) { MPI_Recv ( buf , 256 , MPI_CHAR , other_rank , 0 , MPI_COMM_WORLD , MPI_STATUS_IGNORE ); printf ( "%s \n " , buf ); }                    } demás {   /* Recibir mensaje del proceso #0 */ MPI_Recv ( buf , 256 , MPI_CHAR , 0 , 0 , MPI_COMM_WORLD , MPI_STATUS_IGNORE ); assert ( memcmp ( buf , "Hola " , 6 ) == 0 );             /* Enviar mensaje al proceso #0 */ sprintf ( buf , "El proceso %i se reporta para servicio." , my_rank ); MPI_Send ( buf , 256 , MPI_CHAR , 0 , 0 , MPI_COMM_WORLD );          } /* Derribar la infraestructura de comunicación */ MPI_Finalize (); return 0 ; }   

Cuando se ejecuta con 4 procesos, debería producir el siguiente resultado: [46]

$ mpicc ejemplo.c && mpiexec -n 4 ./a.outTenemos 4 procesos.Proceso 1 reportándose para el servicio.Proceso 2 reportándose para el servicio.Proceso 3 reportándose para el servicio.

Aquí, mpiexecse muestra un comando utilizado para ejecutar el programa de ejemplo con 4 procesos , cada uno de los cuales es una instancia independiente del programa en tiempo de ejecución y tiene rangos asignados (es decir, identificadores numéricos) 0, 1, 2 y 3. El nombre mpiexeces recomendado por el estándar MPI, aunque algunas implementaciones proporcionan un comando similar con el nombre mpirun. El MPI_COMM_WORLDes el comunicador que consta de todos los procesos.

De este modo, se facilita un modelo de programación de un solo programa, múltiples datos ( SPMD ), pero no es obligatorio; muchas implementaciones de MPI permiten iniciar varios ejecutables diferentes en el mismo trabajo MPI. Cada proceso tiene su propio rango, el número total de procesos en el mundo y la capacidad de comunicarse entre ellos, ya sea con comunicación punto a punto (envío/recepción) o mediante comunicación colectiva entre el grupo. Es suficiente que MPI proporcione un programa de estilo SPMD con MPI_COMM_WORLD, su propio rango y el tamaño del mundo para permitir que los algoritmos decidan qué hacer. En situaciones más realistas, la E/S se gestiona con más cuidado que en este ejemplo. MPI no estipula cómo debería funcionar la E/S estándar (stdin, stdout, stderr) en un sistema determinado. Generalmente funciona como se espera en el proceso de rango 0, y algunas implementaciones también capturan y canalizan la salida de otros procesos.

MPI utiliza la noción de proceso en lugar de procesador. Las copias de programa se asignan a procesadores mediante el entorno de ejecución de MPI . En ese sentido, la máquina paralela puede asignarse a un procesador físico, o a N procesadores, donde N es la cantidad de procesadores disponibles, o incluso a algo intermedio. Para lograr la máxima aceleración paralela, se utilizan más procesadores físicos. Este ejemplo ajusta su comportamiento al tamaño del mundo N , por lo que también busca escalar a la configuración del entorno de ejecución sin compilación para cada variación de tamaño, aunque las decisiones del entorno de ejecución pueden variar según la cantidad absoluta de concurrencia disponible.

Adopción del MPI-2

La adopción de MPI-1.2 ha sido universal, en particular en la computación en clúster, pero la aceptación de MPI-2.1 ha sido más limitada. Entre los problemas se incluyen los siguientes:

  1. Las implementaciones de MPI-2 incluyen E/S y gestión de procesos dinámicos, y el tamaño del middleware es sustancialmente mayor. La mayoría de los sitios que utilizan sistemas de programación por lotes no pueden soportar la gestión de procesos dinámicos. La E/S paralela de MPI-2 tiene una buena aceptación. [ cita requerida ]
  2. Muchos programas MPI-1.2 se desarrollaron antes de MPI-2. Las preocupaciones por la portabilidad inicialmente retrasaron la adopción, aunque un apoyo más amplio ha atenuado este problema.
  3. Muchas aplicaciones MPI-1.2 utilizan sólo un subconjunto de ese estándar (16-25 funciones) sin necesidad real de la funcionalidad MPI-2.

Futuro

Algunos aspectos del futuro del MPI parecen sólidos; otros no tanto. El Foro MPI volvió a reunirse en 2007 para aclarar algunas cuestiones del MPI-2 y explorar desarrollos para un posible MPI-3, lo que dio como resultado las versiones MPI-3.0 (septiembre de 2012) [47] y MPI-3.1 (junio de 2015) [48] . El desarrollo continuó con la aprobación del MPI-4.0 el 9 de junio de 2021 [49] y, más recientemente, el MPI-4.1 fue aprobado el 2 de noviembre de 2023. [50]

Las arquitecturas están cambiando, con una mayor concurrencia interna ( multi-core ), un mejor control de concurrencia de grano fino (threading, afinidad) y más niveles de jerarquía de memoria . Los programas multihilo pueden aprovechar estos desarrollos más fácilmente que las aplicaciones de un solo hilo. Esto ya ha producido estándares separados y complementarios para multiprocesamiento simétrico , a saber, OpenMP . MPI-2 define cómo las implementaciones conformes con el estándar deben lidiar con problemas multihilo, pero no requiere que las implementaciones sean multihilo, o incluso seguras para subprocesos. MPI-3 agrega la capacidad de usar paralelismo de memoria compartida dentro de un nodo. Las implementaciones de MPI como Adaptive MPI, Hybrid MPI, Fine-Grained MPI, MPC y otras ofrecen extensiones al estándar MPI que abordan diferentes desafíos en MPI.

El astrofísico Jonathan Dursi escribió un artículo de opinión en el que calificaba de obsoleto el MPI, señalando tecnologías más nuevas como el lenguaje Chapel , Unified Parallel C , Hadoop , Spark y Flink . [51] Al mismo tiempo, casi todos los proyectos del Exascale Computing Project se basan explícitamente en MPI; se ha demostrado que MPI se escala a las máquinas más grandes a principios de la década de 2020 y se considera ampliamente que seguirá siendo relevante durante mucho tiempo.

Véase también

Referencias

  1. ^ "Interfaz de paso de mensajes: informática de alto rendimiento". hpc.nmsu.edu . Consultado el 6 de agosto de 2022 .
  2. ^ Walker DW (agosto de 1992). Estándares para el paso de mensajes en un entorno de memoria distribuida (PDF) (Informe). Oak Ridge National Lab., TN (Estados Unidos), Centro de Investigación sobre Computación Paralela (CRPC). pág. 25. OSTI  10170156. ORNL/TM-12147 . Consultado el 18 de agosto de 2019 .
  3. ^ The MPI Forum, CORPORATE (15-19 de noviembre de 1993). "MPI: A Message Passing Interface". Actas de la conferencia ACM/IEEE de 1993 sobre supercomputación . Supercomputing '93. Portland, Oregon, EE. UU.: ACM. pp. 878-883. doi :10.1145/169627.169855. ISBN 0-8186-4340-4.
  4. ^ Nielsen, Frank (2016). "2. Introducción a MPI: la interfaz MessagePassing". Introducción a HPC con MPI para la ciencia de datos. Springer. pp. 195–211. ISBN 978-3-319-21903-5.
  5. ^ Gropp, Lusk y Skjellum 1996, pág. 3
  6. ^ Sur, Sayantan; Koop, Matthew J.; Panda, Dhabaleswar K. (4 de agosto de 2017). "MPI y comunicación: MPI escalable y de alto rendimiento sobre InfiniBand con uso reducido de memoria: un análisis de rendimiento en profundidad". Actas de la conferencia ACM/IEEE de 2006 sobre supercomputación - SC '06 . ACM. pág. 105. doi :10.1145/1188455.1188565. ISBN 978-0769527000.S2CID818662  .​
  7. ^ KNEM: comunicación MPI intranodo de alto rendimiento "MPICH2 (desde la versión 1.1.1) utiliza KNEM en el LMT de DMA para mejorar el rendimiento de mensajes grandes dentro de un solo nodo. Open MPI también incluye compatibilidad con KNEM en su componente SM BTL desde la versión 1.5. Además, NetPIPE incluye un backend KNEM desde la versión 3.7.2".
  8. ^ "Preguntas frecuentes: Ajuste de las características de tiempo de ejecución de las comunicaciones MPI sm". www.open-mpi.org .
  9. ^ https://software.intel.com/en-us/articles/an-introduction-to-mpi-3-shared-memory-programming?language=en "El estándar MPI-3 introduce otro enfoque a la programación híbrida que utiliza el nuevo modelo de memoria compartida MPI (SHM)"
  10. ^ Memoria compartida y MPI 3.0 "Se pueden ejecutar varios análisis comparativos para determinar qué método es mejor para una aplicación en particular, ya sea utilizando MPI + OpenMP o las extensiones MPI SHM. En un caso de prueba bastante simple, las aceleraciones en comparación con una versión base que utilizaba comunicación punto a punto fueron hasta 5 veces mayores, según el mensaje".
  11. ^ Uso de la memoria compartida MPI-3 como sistema de programación multinúcleo (diapositivas de la presentación en formato PDF)
  12. ^ Índice — Septiembre de 1994, 8 (3-4). Hpc.sagepub.com. Recuperado el 24 de marzo de 2014.
  13. ^ Documentos del MPI. Mpi-forum.org. Recuperado el 24 de marzo de 2014.
  14. ^ Gropp, Lusk y Skjellum 1999b, págs. 4-5
  15. ^ MPI: A Message-Passing Interface StandardVersion 3.1, Message Passing Interface Forum, 4 de junio de 2015. http://www.mpi-forum.org. Consultado el 16 de junio de 2015.
  16. ^ ab "Reglas de coincidencia de tipos". mpi-forum.org .
  17. ^ "Página de manual de MPI_Gather(3) (versión 1.8.8)". www.open-mpi.org .
  18. ^ "MPI_Obtener_dirección". www.mpich.org .
  19. ^ Justificación del mecanismo de contenido/esqueleto de Boost.MPI (los gráficos de comparación de rendimiento se generaron utilizando NetPIPE )
  20. ^ Gropp, Lusk y Skjelling 1999b, pág. 7
  21. ^ Gropp, Lusk y Skjelling 1999b, págs. 5-6
  22. ^ "Multiplicaciones de matrices y vectores dispersos utilizando la biblioteca MPI I/O" (PDF) .
  23. ^ "Tamizado de datos y E/S colectiva en ROMIO" (PDF) . IEEE. Febrero de 1999.
  24. ^ Chen, Yong; Sun, Xian-He; Thakur, Rajeev; Roth, Philip C.; Gropp, William D. (septiembre de 2011). "LACIO: una nueva estrategia de E/S colectiva para sistemas de E/S paralelas". Simposio internacional IEEE de procesamiento paralelo y distribuido de 2011. IEEE. págs. 794–804. CiteSeerX 10.1.1.699.8972 . doi :10.1109/IPDPS.2011.79. ISBN .  978-1-61284-372-8. Número de identificación del sujeto  7110094.
  25. ^ Teng Wang; Kevin Vasko; Zhuo Liu; Hui Chen; Weikuan Yu (2016). "Mejorar la entrada/salida paralela con agregación entre paquetes". Revista internacional de aplicaciones informáticas de alto rendimiento . 30 (2): 241–256. doi :10.1177/1094342015618017. S2CID  12067366.
  26. ^ Wang, Teng; Vasko, Kevin; Liu, Zhuo; Chen, Hui; Yu, Weikuan (noviembre de 2014). "BPAR: un marco de agregación paralela basado en paquetes para la ejecución de E/S desacoplada". Taller internacional de 2014 sobre sistemas informáticos escalables con uso intensivo de datos . IEEE. págs. 25–32. doi :10.1109/DISCS.2014.6. ISBN. 978-1-4673-6750-9. Número de identificación del sujeto  2402391.
  27. ^ cea-hpc. "cea-hpc/wi4mpi: Interfaz de contenedor para MPI". GitHub .
  28. ^ mpicc. Mpich.org. Recuperado el 24 de marzo de 2014.
  29. ^ Mpi.NET puro
  30. ^ "MPI.NET: Biblioteca C# de alto rendimiento para paso de mensajes". www.osl.iu.edu .
  31. ^ "Página de inicio de mpiJava". www.hpjava.org .
  32. ^ "Introducción a la API de mpiJava". www.hpjava.org .
  33. ^ "La especificación API de MPJ". www.hpjava.org .
  34. ^ "Proyecto MPJ Express". mpj-express.org .
  35. ^ JuliaParallel/MPI.jl, Parallel Julia, 2019-10-03 , consultado el 2019-10-08
  36. ^ "Xavier Leroy - Software". cristal.inria.fr .
  37. ^ Archivos de la lista de correo Caml > Mensaje de Yaron M. Minsky. Caml.inria.fr (15 de julio de 2003). Recuperado el 24 de marzo de 2014.
  38. ^ "Introducción a la GP paralela" (PDF) . pari.math.u-bordeaux.fr .
  39. ^ "mpi4py".
  40. ^ "numba-mpi".
  41. ^ "mpi4jax".
  42. ^ "Archivo de código de Google: almacenamiento a largo plazo para alojamiento de proyectos de código de Google". code.google.com .
  43. ^ Ahora parte de Pydusa
  44. ^ Yu, Hao (2002). "Rmpi: Computación estadística paralela en R". R News .
  45. ^ Chen, Wei-Chen; Ostrouchov, George; Schmidt, Drew; Patel, Pragneshkumar; Yu, Hao (2012). "pbdMPI: Programación con Big Data - Interfaz a MPI".
  46. ^ El fragmento de salida se generó en un sistema de escritorio Linux común y corriente con Open MPI instalado. Las distribuciones suelen colocar el comando mpicc en un paquete openmpi-devel o libopenmpi-dev y, a veces, hacen necesario ejecutar "module add mpi/openmpi-x86_64" o algo similar antes de que mpicc y mpiexec estén disponibles.
  47. ^ https://www.mpi-forum.org/docs/mpi-3.0/mpi30-report.pdf
  48. ^ https://www.mpi-forum.org/docs/mpi-3.1/mpi31-report.pdf
  49. ^ https://www.mpi-forum.org/docs/mpi-4.0/mpi40-report.pdf
  50. ^ https://www.mpi-forum.org/docs/mpi-4.1/mpi41-report.pdf
  51. ^ "El HPC está muriendo y el MPI lo está matando". www.dursi.ca .

Lectura adicional

Enlaces externos