Message Passing Interface

De Viquipèdia
Salta a: navegació, cerca

MPI (Message-Passing Interface, interfície de pas de missatges)[1] és una especificació d'interfície de biblioteca en el que totes les operacions són expressades com a funcions, subrutines o mètodes enllaçats normalment als llenguatges C i Fortran. Cal destacar que aquesta especificació és la més utilitzada actualment per a la programació concurrent en entorns en la que la comunicació es fa a través de missatges i se la considera l'estàndard de referència.

L'objectiu principal de l'MPI és formar un estàndard que sigui àmpliament utilitzat en programes que requereixin utilitzar missatges per comunicar-se, per això, la interfície intenta ser pràctica, portable, eficient i flexible per tal d'incrementar la productivitat a l'hora de fer aquest tipus d'algoritmes.

Els altres objectius de l'MPI es poden trobar en la següent llista:

  1. Dissenyar una interfície de programació d'aplicacions
  2. Permetre una comunicació eficient: això s'assoleix evitant les còpies de memòria a memòria, permetent solapar la comunicació amb la computació i afegir sobrecarrega per permetre la comunicació dels co-processadors quan sigui possible
  3. Permetre que les implementacions es puguin utilitzar en entorns heterogenis
  4. Permetre dotar als llenguatges C i Fortran de directives convenients
  5. Assolir una interfície de comunicació fiable: l'usuari no necessita bregar amb els errors de les comunicacions, ja que aquestes comunicacions es fan en un subsistema de comunicació intern
  6. Definir una interfície que pugui ser implementada en qualsevol plataforma dels venedors sense haver de modificar les comunicacions internes i el software del sistema
  7. La semàntica de la interfície hauria de ser independent del llenguatge
  8. La interfície hauria de ser dissenyada per assegurar la seguretat dels threads

Història[modifica | modifica el codi]

La estandardització[2] de la interfície de pas missatges va començar-se a desenvolupar gràcies al patrocini del Centre d'Investigació en Computació Paral·lela de Williamsburg, Virgínia, Estats Units (Abril 29-30 de 1992). Va sorgir la primera versió preliminar, anomenada MPI1, que estava principalment enfocada a les comunicacions Punt-A-Punt, sense incloure rutines de comunicació col·lectiva. L'estàndard final va ser presentat a la conferencia de Supercomputació al 1993.

A causa de la utilitat i potencial d'aquest projecte, es va continuar actualitzant aquest estàndard de comunicació. D'aquesta manera, al 1994 es va publicar el MPI-1 i, al 1997, el MPI-2.

Conceptes[modifica | modifica el codi]

MPI ofereix una extensa gamma d'habilitats.[3] Els següents conceptes ajuden a la comprensió i proporcionen un context per a totes aquestes habilitats, ajudant al programador per decidir quina funcionalitat utilitzar en els seus programes.

Comunicador[modifica | modifica el codi]

Els objectes Comunicadors indiquen la quantitat de processos que s'utilitzaran i connecten grups de processos a una sessió MPI.

Un cop fet això, cada comunicador dóna a cadascun dels seus processos un identificador i els ordena formant una topologia. A més el MPI també té grups explícits, però s'utilitzen principalment per organitzar grups de processos abans que un altre comunicador els adopti. MPI comprèn les operacions de comunicació dins del comunicador, així com les comunicacions bilaterals entre comunicadors. Al MPI-1, són més utilitzades les comunicacions internes, mentre que al MPI-2 són més comuns les comunicacions bilaterals, ja que inclou mètodes de gestió de comunicacions col·lectives.

Els comunicadors poden ser fraccionats mitjançant diversos comandaments MPI. Entre aquestes ordres s'inclou MPI_COMM_SPLIT, on cada procés s'ajunta amb un subcomunicador, identificat amb un color, i s'anuncia que ell també pertany a aquell color.

Bàsiques Punt-a-Punt[modifica | modifica el codi]

Un gran nombre de funcions MPI involucren la comunicació entre dos processos.

Un exemple popular és MPI_Send, que permet que un procés enviï un missatge a un altre procés. Les operacions Punt-a-Punt, que així és com s'anomenen, són particularment útils en comunicacions regulars com, per exemple, una arquitectura amb dades en paral·lel en la qual cada processador intercanvia rutinàriament regions de dades amb altres processadors després de realitzar certs càlculs, o una arquitectura Mestre/Esclau, on el mestre envia dades d'una tasca a un esclau cada cop que aquest acaba amb la tasca a la qual està treballant.

MPI-1 té especificats mecanismes tant per sistemes de comunicacions Punt-a-Punt bloquejats i no, com el mecanisme denominat "Llest-Enviat", on una sol·licitud d'enviament només pot fer-se quan una resposta de recepció d'aquella mateixa transmesa ha sigut rebuda.

Bàsiques de comunicació col·lectiva[modifica | modifica el codi]

Les funcions col·lectives involucren comunicacions entre tots els processos d'un grup de procés.

Una funció típica és l'anomenada MPI_Bcast (abreviatura de l'angles "Broadcast"). Aquesta funció pren les dades d'un node i les envia a tots els processos d'un grup de procés. Una operació inversa és MPI_Reduce, que pren les dades de tots els processos d'un grup, realitza una operació amb ells i emmagatzema els resultats en un únic node. MPI_Reduce sovint és útil a l'inici o al final d'un gran càlcul distribuït, on cada processador treballa amb una porció de les dades i, a continuació, és combinen tots els resultats.

Hi ha operacions més sofisticades, com MPI_Alltoall, que reorganitza n elements de dades tals que el node n-èsim obté l'element n-èsim de les dades.

Tipus de dades derivades[modifica | modifica el codi]

Moltes funcions MPI requereixen que s'especifiqui el tipus de dades que s'enviaran entre processos.

El motiu d'això és que MPI té com a objectiu el suport a entorns heterogenis on les dades poden ser representades de maneres diferents a cada node (Per exemple, poden tenir diferents arquitectures de CPU amb ordres de bytes diferents). En aquest cas, les implementacions MPI poden realitzar una conversió de dades. Com que el llenguatge C no permet que es passin tipus de dades com a paràmetre, MPI predefineix una sèrie de constants MPI_INIT, MPI_CHARMPI_DOUBLE, que corresponen a intchardouble, etc.

Informació Bàsica per la implementació[modifica | modifica el codi]

Tipus de dades[modifica | modifica el codi]

  1. Enter (integer)
    • Signed:
      • MPI_CHAR
      • MPI_SHORT
      • MPI_INT
      • MPI_LONG
    • Unsigned:
      • MPI_UNSIGNED_CHAR
      • MPI_UNSIGNED_SHORT
      • MPI_UNSIGNED_INT
      • MPI_UNSIGNED_LONG
  2. Coma flotant (Float)
    • MPI_FLOAT
    • MPI_DOUBLE
    • MPI_LONG_DOUBLE

Funcions Bàsiques[4][modifica | modifica el codi]

Explicació Implementació en C Implementació en Fortran
Inicialitzar MPI int MPI_Init(int *argc, char **argv) integer ierror

call MPI_Init(ierror)

Determinar el nombre de processadors MPI int MPI_Comm_size(MPI_Comm comm, int *size) integer comm,size,ierror

call MPI_Comm_Size(comm,size,ierror)

Identificador de un processador, si el rank == 0 int MPI_Comm_rank(MPI_Comm comm, int *rank) integer comm,rank,ierror

call MPI_Comm_Rank(comm,rank,ierror)

Finalitza MPI (té que ser cridat per a tots els processadors) int MPI_Finalize() CALL MPI_Finalize(ierror)
Envia un missatge a un altre procesador MPI int MPI_Send (void *buf,int count, MPI_Datatype

datatype, int dest, int tag, MPI_Comm comm)

<type> buf(*)

integer count, datatype,dest,tag

integer comm, ierror

call MPI_Send(buf,count, datatype, dest, tag, comm, ierror)

Rep el missatge d'un processador MPI int MPI_Recv (void *buf,int count, MPI_Datatype

datatype, int source, int tag, MPI_Comm comm, MPI_Status *status)

<type> buf(*)

integer count, datatype, source,tag

integer comm, status, ierror

call MPI_Recv(buf,count, datatype, source, tag, comm, status, ierror)

Addicionalment també es pot utilitzar MPI_Get_processor_name() per trobar el nom d'un processador extern.

Exemples d'implementació en C[modifica | modifica el codi]

Hello World Exemple[modifica | modifica el codi]

 
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <mpi.h>


int main(int argc, char **argv)
{
    char nom[256];
    int rank, nombre_processos,etiqueta=999;
    // Inicialitza la infraestructura per la comunicació 
    MPI_Init(&argc, &argv);
    
    // Identifica aquest procés
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    // Identifica el total de processos que hi ha actualment
    MPI_Comm_size(MPI_COMM_WORLD, &nombre_processos);
    

// El primer procès rep dels altres processos un missatge i ho imprimeix per pantalla
    if (rank == 0 )
    {
      MPI_STATUS estat;
      
      for (int origen=1; origen < nombre_processos;origen++)
      {
        MPI_RECV(nom,sizeof(nom),MPI_CHAR,origen,etiqueta,MPI_COMM_WORLD,&status);
        printf(" Missatge des del procés %d de un total de %d processos \n ",origen,tamany);
      }
    }
    else // els altres processos envia un missatge 
    {
        int desti = 0; 
        MPI_SEND(nom,sizeof(nom),MPI_CHAR,desti,etiqueta,MPI_COMM_WORLD);
    }

   // Finalitza la infraestructura de comunicació
   MPI_Finalize();
   return 0;
}

Referències[modifica | modifica el codi]

  1. «MPI Forum» (en en). [Consulta: 14 juliol 2017].
  2. «MPI Documents» (en en). [Consulta: 18 maig 2017].
  3. «Basic MPI».
  4. Schwarz, Susan. «Basic MPI Functions (Subroutines) and Data types». [Consulta: 18 maig 2017].