Monografias.com > Sin categoría
Descargar Imprimir Comentar Ver trabajos relacionados

Programación con Paso de Mensajes (MPI) (página 3)




Enviado por Pablo Turmero



Partes: 1, 2, 3, 4

Monografias.com
MPIComunicación punto a punto.
MPI define un envío como finalizado cuando el emisor puede reutilizar, sin problemas de causar interferencias, el buffer de emisión que tenía el mensaje.

Se puede entender que tras hacer un send (envío) bloqueante podemos reutilizar el buffer asociado sin problemas.

Pero tras hacer un send no bloqueante tenemos que ser muy cuidadosos con las manipulaciones que se realizan sobre el buffer, bajo el riesgo de alterar inadvertidamente la información que se está enviando.

Monografias.com
MPIComunicación punto a punto.
Al margen de si la función invocada es bloqueante o no, el programador puede tener un cierto control sobre la forma en la que se realiza y completa un envío. MPI define, en relación a este aspecto, 4 modos de envío:

básico(basic)
con buffer (buffered)
síncrono (synchronous)
listo (ready).

Monografias.com
MPIComunicación punto a punto.
Cuando se hace un envío con buffer se guarda inmediatamente, en un buffer al efecto en el emisor, una copia del mensaje. La operación se da por completa en cuanto se ha efectuado esta copia. Si no hay espacio en el buffer, el envío fracasa.

Si se hace un envío síncrono, la operación se da por terminada sólo cuando el mensaje ha sido recibido en destino.

El modo de envío básico no especifica la forma en la que se completa la operación: es algo dependiente de la implementación. Normalmente equivale a un envío con buffer para mensajes cortos y a un envío síncrono para mensajes largos. Se intenta así agilizar el envío de mensajes cortos a la vez que se procura no perder demasiado tiempo realizando copias de la información.

En cuanto al envío en modo listo, sólo se puede hacer si antes el otro extremo está preparado para una recepción inmediata. No hay copias adicionales del mensaje (como en el caso del modo con buffer), y tampoco podemos confiar en bloquearnos hasta que el receptor esté preparado.

Monografias.com
MPIComunicación punto a punto. Básica
El resultado de la combinación de dos modelos y cuatro modos de comunicación nos da 8 diferentes funciones de envío.

Funciones de recepción sólo hay dos, una por modelo.

MPI_Send() y MPI_Recv() que son, respectivamente, las funciones de envío y recepción básicas bloqueantes.

int MPI_Send(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm);

int MPI_Recv(void* buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Status *status);

Monografias.com
MPIComunicación punto a punto. Básica
Enviando y recibiendo mensajes

Preguntas:
¿Donde está la info?
¿Que tipo de info se envía?
¿Que cantidad de info se envía?
¿A quién se envía la info?
¿Como identifica el receptor el mensaje?

Monografias.com
MPIComunicación punto a punto. Básica
En MPI se especifica con address, datatype y count: count copias de un dato del tipo datatype que se encuentran (o se van a dejar) en memoria a partir de la dirección indicada por buf.

Dest es el identificador del proceso destinatario del mensaje.

Source es el identificador del emisor del cual esperamos un mensaje. Si no nos importa el origen del mensaje, podemos poner MPI_ANY_SOURCE.

Tag es una etiqueta que se puede poner al mensaje. Suele emplearse para distinguir entre diferentes clases de mensajes. El receptor puede elegir entre recibir sólo los mensajes que tengan una etiqueta dada, o aceptar cualquier etiqueta (MPI_ANY_TAG).

Comm es un comunicador (comunicador universal MPI_COMM_WORLD).

Status es un resultado que se obtiene cada vez que se completa una recepción, y nos informa de aspectos tales como el tamaño del mensaje recibido, la etiqueta del mensaje y el emisor del mismo.

Monografias.com
MPIComunicación punto a punto. Básica
Si queremos saber el tamaño de un mensaje, lo haremos con la función MPI_Get_count():

int MPI_Get_count(MPI_Status *status, MPI_Datatype datatype, int *count);

MPI_Isend() y MPI_Irecv() son las funciones de emisión/recepción básicas no bloqueantes.

int MPI_Isend(void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm, MPI_Request *request);
int MPI_Irecv(void* buf, int count, MPI_Datatype datatype, int source, int tag, MPI_Comm comm, MPI_Request *request);

Monografias.com
MPIComunicación punto a punto. Básica
Asociadas a MPI_Isend() y MPI_Irecv() existen otras tres funciones:

int MPI_Wait(MPI_Request *request, MPI_Status *status);
int MPI_Test(MPI_Request *request, int *flag, MPI_Status *status);
int MPI_Cancel(MPI_Request *request);

MPI_Wait() toma como entrada un recibo (request), y bloquea al proceso hasta que la operación correspondiente termina.

Hacer un MPI_Isend() seguido de un MPI_Wait() equivale a hacer un envío bloqueante.

Sin embargo, entre la llamada a la función de envío y la llamada a la función de espera el proceso puede haber estado haciendo cosas útiles, es decir, consigue solapar parte de cálculo de la aplicación con la comunicación.

Monografias.com
MPIComunicación punto a punto. Básica
Asociadas a MPI_Isend() y MPI_Irecv() existen otras tres funciones:

int MPI_Wait(MPI_Request *request, MPI_Status *status);
int MPI_Test(MPI_Request *request, int *flag, MPI_Status *status);
int MPI_Cancel(MPI_Request *request);

Cuando no interesa bloquearse, sino simplemente saber si la operación ha terminado o no, podemos usar MPI_Test(). Esta función actualiza un flag que se le pasa como segundo parámetro. Si la función ha terminado, este flag toma el valor 1, y si no ha terminado pasa a valer 0.

Por último, MPI_Cancel() nos sirve para cancelar una operación de comunicación pendiente, siempre que ésta aún no se haya completado.

Monografias.com
MPIEjemplos
Calcular el valor de la integral usando una suma de rectángulos:

Monografias.com
MPIEjemplos.
program main
include 'mpif.h'

double precision PI25DT
parameter (PI25DT = 3.141592653589793238462643d0)
double precision mypi,pi,h,suma,x,f,a
double precision startime,endtime
integer n,myid,numprocs,i,ierr

! FUNCION PARA INTEGRAR

f(a)=4.d0/(1.d0+a*a)

call MPI_INIT(ierr)
call MPI_COMM_RANK(MPI_COMM_WORLD,myid,ierr)
call MPI_COMM_SIZE(MPI_COMM_WORLD,numprocs,ierr)

Monografias.com
MPIEjemplos.
10 if(myid .eq. 0) then
print *, 'Introduzca el numero de intervalos (0 salir)'
read(*,*) n
print *, 'lo he leido y es ', n
endif

! BROADCAST N

startime=MPI_WTIME()
call MPI_BCAST(n,1,MPI_INTEGER,0,MPI_COMM_WORLD,ierr)

! CHEQUEAR POR POSIBLE SALIDA

if (n .le. 0) goto 30

Monografias.com
MPIEjemplos.
! CALCULAR EL TAMANO DEL INTERVALO

h=1.0d0/n
suma=0.0d0

do 20 i=myid+1,n,numprocs
x=h*(dble(i)-0.5d0)
suma=suma+f(x)
20 continue
mypi=h*suma

! RECOLECTAR TODAS LAS SUMAS PARCIALES
call MPI_REDUCE(mypi,pi,1,MPI_DOUBLE_PRECISION,MPI_SUM,0,
MPI_COMM_WORLD,ierr)

Monografias.com
MPIEjemplos.
! EL NODO 0 IMPRIMIRA LA RESPUESTA

entime=MPI_WTIME()
if(myid .eq. 0) then
print *, 'pi es', pi, 'Error es ', abs(pi-PI25DT)
print *, 'tiempo es ', (endtime-starttime), 'segundos'
endif
! goto 10

30 call MPI_FINALIZE(ierr)

stop
end

Monografias.com
MPIEjemplos.
#include using namespace std;
int main(int argc, char **argv)
{
int sum = 0;
for(int i=1;i<=1000;i=i+1)
sum = sum + i;
cout << "The sum from 1 to 1000 is: "<< sum << endl;
}

Resultado: The sum from 1 to 1000 is: 500500
SUMA. Algoritmo secuencial

Monografias.com
MPIEjemplos.
#include #include “mpi.h”
using namespace std;
int main(int argc, char ** argv)
{
int mynode, totalnodes;
int sum = 0,startval,endval,accum;
MPI_Status status;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD, &totalnodes);
MPI_Comm_rank(MPI_COMM_WORLD, &mynode);
startval = 1000*mynode/totalnodes+1;
endval = 1000*(mynode+1)/totalnodes;
SUMA. Algoritmo paralelo

Monografias.com
MPIEjemplos.
for(int i=startval;i<=endval;i=i+1)
sum = sum + i;
if(mynode!=0)
MPI_Send(&sum, 1, MPI_INT, 0, 1, MPI_COMM_WORLD);
else
for(int j=1;j<< "The sum from 1 to 1000 is: "<< sum << endl;
MPI_Finalize();
}
SUMA. Algoritmo paralelo

Monografias.com
MPIEjemplos.
SUMA. Algoritmo paralelo

Compilación: mpicxx –o sumaparalelo sumaParalelo.cpp

Ejecución: mpiexec -n 4 ./suma_para
Resultado: The sum from 1 to 1000 is: 500500

Monografias.com
MPIEjemplos.
Programa greetings

/* Envío de un mensaje desde todos los procesos con rank!= 0 al proceso 0.
El proces 0 imprime los mensajes */

#include
#include
#include "mpi.h"
main(int argc, char* argv[]) {
int my_rank;
int p;
int source; /* origen */
int dest; /* destino */
int tag = 0;
char message[100];
MPI_Status status;

MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD, &p);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

Monografias.com
MPIEjemplos.
if (my_rank != 0) {
/* Creamos el mensaje */
sprintf(message, "Greetings from process %d!", my_rank);
dest = 0;
/* Longitud strlen+1 porque en C se añade al final de una cadena '' */
MPI_Send(message, strlen(message)+1, MPI_CHAR, dest, tag, MPI_COMM_WORLD);
}
else { /* my_rank == 0 */
for (source = 1; source < p; source++) {
MPI_Recv(message, 100, MPI_CHAR, source, tag, MPI_COMM_WORLD, &status);
printf("%sn", message);
}
}
MPI_Finalize();
}

Partes: 1, 2, 3, 4
 Página anterior Volver al principio del trabajoPágina siguiente 

Nota al lector: es posible que esta página no contenga todos los componentes del trabajo original (pies de página, avanzadas formulas matemáticas, esquemas o tablas complejas, etc.). Recuerde que para ver el trabajo en su versión original completa, puede descargarlo desde el menú superior.

Todos los documentos disponibles en este sitio expresan los puntos de vista de sus respectivos autores y no de Monografias.com. El objetivo de Monografias.com es poner el conocimiento a disposición de toda su comunidad. Queda bajo la responsabilidad de cada lector el eventual uso que se le de a esta información. Asimismo, es obligatoria la cita del autor del contenido y de Monografias.com como fuentes de información.

Categorias
Newsletter