Comunicadores Para recibir un mensaje no siempre es necesario especificar el ‘rank’ de la fuente aunque si lo es para enviarlo
‘context’ sirve para evitar conflictos entre el codigo de diferentes programadores. Se añade automaticamente
MPI_COMM_SELF es un comunicador que solo engloba a un solo miembro
MPI_COMM_PARENT engloba los grupos de un proceso y de su proceso padre
Inicializar, dirigir y finalizar comunicación Iniciar y finalizar comunicación Identificar número de procesos, qué proceso corre en cada procesador y crear subgrupos de procesadores MPI_Init, MPI_Finalice Comunicación punto a punto MPI_Send, MPI_Recv Comunicación colectiva MPI_Bcast, MPI_Scatter, MPI_Gather, MPI_Reduce Creación de tipos de datos MPI_Type_struct Clases de llamadas MPI
Un procesador envía y otro recibe Comunicación elemental en MPI Dos modos de comunicación Bloqueante: La rutina de enviar o recibir no termina hasta que la operación se ha completado. Asegura que los datos llegan al receptor sin error. No bloqueante: La función envía o recibe inmediatamente. El procesador puede hacer otras tareas durante el envío Cuatro procedimientos para transmitir mensajes standard – no hay garantía de que el recv se inicio synchronous – se completa cuando el recv comenzó. buffered – Se completa cuando el dato se copio al buffer local. (No implica que se recibió bien) ready – El usuario dice cuando se completo la recepción
Los recv son mas sencillos: Se completan cuando el data esta listo para usarse Comunicación punto a punto
MPI_Send (void *buf, int count, MPI Datatype dtype, int dest, int tag, MPI_Comm comm);
MPI_Recv (void *buf, int count, MPI_Datatype dtype, int source, int tag, MPI_Comm comm, MPI_status *status);
buf: localización en memoria de los datos count: Número de datos del tipo indicado enviados o recibidos dtype: tipo de datos enviados o recibidos dest/source: procesador destino/fuente tag: etiqueta de comunicación comm: comunicador de envío o recepción status: código de retorno de la operación de recepción Comunicación punto a punto
Comunicaciones de un procesador a varios y de varios procesadores a uno Se reduce la posibilidad de error Una llamada a una rutina colectiva reemplaza a varias llamadas a rutinas punto a punto Código fuente más fácil de leer Simplifica depuración y mantenimiento Normalmente, la rutina colectiva es más rápida Está más optimizada que su equivalente expresada por medio de rutinas punto a punto Comunicación colectiva
Operación broadcast: Un único proceso envía copia de los mismos datos a todos los procesos de un grupo
MPI_Bcast (void *buf, int count, MPI_Datatype dtype, int root, MPI_Comm comm);
buf: localización en memoria de los datos count: Número de datos del tipo indicado enviados dtype: tipo de datos enviados root: procesador fuente comm: comunicador de envío Comunicación colectiva
Operación reduction: Un único proceso recoge datos de todos los procesos de un grupo y los combina según una operación aritmética
MPI_Reduce (void *sendbuf, void *recvbuf, int count, MPI_Datatype dtype, MPI_Op op, int root, MPI_Comm com);
sendbuf: localización en memoria de los datos recvbuf: buffer donde se combinan los datos recibidos count: número de datos del tipo indicado recibidos dtype: tipo de datos recibidos op: operación aritmética que se aplica a los datos recibidos root: procesador destino com: comunicador de recepción Comunicación colectiva
Operación scatter: Los datos de un procesador se dividen en N bloques (N nº de procesos), y se envían a cada proceso según orden de rank
MPI_Scatter (void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm); Operación gather: Paso inverso, se agrupan los datos de todos los procesos y se envían a uno solo
MPI_Gather (void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm); Comunicación colectiva
“Hola Mundo” en C con MPI #include “mpi.h” #include int main(int argc, char **argv) { int rank, size; MPI_Init (&argc, &argv); MPI_Comm_rank (MPI_COMM_WORLD, &rank); MPI_Comm_size (MPI_COMM_WORLD, &size); printf( “Hola Mundo! Soy el proceso %d de %dn”, rank,size); MPI_Finalize (); exit (0); } Hola Mundo C
#define CONMPI #ifdef CONMPI #include "mpi.h" #endif
main(int argc, char *argv[]) { int nprocs=1,rank=0; #ifdef CONMPI MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD,&nprocs); MPI_Comm_rank(MPI_COMM_WORLD,&rank); // printf("proceso %i de %i n",rank,nprocs); #endif DEFINES
#ifdef CONMPI //Broadcasteo la info MPI_Bcast(&k,uno, MPI_DOUBLE,cero,MPI_COMM_WORLD); MPI_Bcast(&v,uno, MPI_DOUBLE,cero, MPI_COMM_WORLD); . . . #endif DEFINES
#ifdef CONMPI if(rank==cero) { Temptot=(double*)malloc(sizeof(double)*nprocs*Neq); curtot=(double*)malloc(sizeof(double)*nprocs*Neq); #endif
/*Abro archivos donde guardo los datos (en p=cero)*/ fp1=fopen("Mag.dat","a+"); fp2=fopen("Prom.dat","a+");
#ifdef CONMPI } #endif DEFINES
#ifdef CONMPI if(rank==cero) { start=MPI_Wtime(); #else start=clock(); #endif #ifdef CONMPI } #endif DEFINES
Barrier: MPI_Barrier(MPI_COMM_WORLD); #ifdef CONMPI if(rank==cero) { end=MPI_Wtime(); #else end=clock(); #endif
FINALIZE #ifdef CONMPI MPI_Finalize(); #endif Mido tiempos, imprimo en rank cero, libero memoria en rank cero y finalizo
Mediciones de eficiencia y escalabilidad Speed Up Tiempo Paralelo/(Tiempo Serie) teórico: recta!
Eficiencia P*Tiempo Paralelo/(Tiempo Serial) teórico: Unidad
Mediciones
Página anterior | Volver al principio del trabajo | Página siguiente |