PROGRAMACIÓN
PARALELA MPI
PROGRAMACIÓN 6
DESCRIPCIÓN GENERAL
• Sistemas que emplean paralelismo explícito
• Trabajo en “cluster”
• Consistirá en considerar los programas estructurados en procesos comunicados entre sí por
canales
• Dividiremos la programación en procesos independientes
• flujo de instrucciones secuencial
• Los procesos se comunican a través de canales de intercambian mensajes :
• datos de entrada, salida e intermedios
• puertos de entrada-salida
PROGRAMAR EN PARALELO
• Aspectos a la hora de programar
• Incrementar al máximo el rendimiento -> localidad
• Escalabilidad -> dinámico y adaptable a los nodos
• Proceso para programar en paralelo
• Fragmentación -> Funcional y datos
• Comunicación
• Aglomeración - > Agrupar tareas -> Minimizar comunicaciones
• Mapeo -> Asignar procesos a nodos -> Tantos procesos como maquinas
COMUNICADORES
Un comunicador es una entidad virtual que representa a un número de procesos que se
pueden comunicar entre sí.
• Los procesos se pueden comunicar si se encuentran en el mismo comunicador.
• Cada proceso puede ser miembro de varios comunicadores.
• Un proceso se identifican con un numero
• Un comunicador se identifica con un nombre
ESTRUCTURA DEL PROGRAMA <MPI.H>
• int MPI_Init(&argc, &argv[]) -> Primera función - > Crea un comunicador
• int MPI_Get_processor_name(char *name, int *resultlen) -> PC que ejecuta el proceso
• int MPI_Finalize( ) -> Última función
• Comunicadores
• Rango -> Identificar qué tareas deben realizar y cuales no. (repartir o calcular)
• int MPI_Comm_rank(MPI_Comm comm, int *rank)
• Tamaño -> Número de procesos que lo componen
• int MPI_Comm_size(MPI_Comm comm, int *size)
CÓDIGO
#include <mpi.h>
int main (int argc,char *argv[])
{
int mirango,tamano;
int longitud;
char nombre[10];
MPI_Init (&argc,&argv);
MPI_Comm_rank (MPI_COMM_WORLD,&mirango);
MPI_Comm_size (MPI_COMM_WORLD,&tamano);
MPI_Get_processor_name (nombre,&longitud);
printf("Maquina %s> Proceso %d de %d: Hola Mundo!\n", nombre, mirango, tamano);
fflush(stdout);
MPI_Finalize();
return 0;
}
COMUNICACIÓN EN PROCESOS
EJERCICIO -> PUNTO A PUNTO
Partes del msj
• Difusión
• Envoltura
• Punto a punto
• Fuente: Identificación (rango) del emisor.
• Punto a multipunto (broadcast)
• Destino: Identificación (rango) del receptor.
• Multipunto a punto
• Comunicador: Nombre del comunicador al que pertenecen
• Sincronismo fuente y destino.
• Sincronos -> Con bloque • Etiqueta: Número que emplean emisor y receptor para
clasificar los mensajes.
• Asincrono -> En background
• Cuerpo
• Buffer: Zona de memoria en la que reside la información
Tipo de datos
• Cuenta: Número de datos del tipo definido que componen el
mensaje.
MPI dispone de sus propios tipos de datos estándar, de
manera que los hace independientes de la máquina o
máquina
• int MPI_Send(void *buf, int count, MPI_Datatype
dtype, int dest, int tag, MPI_Comm comm)
• int MPI_Recv(void *buf, int count, MPI_Datatype
dtype, int source, int tag, MPI_Comm comm,
MPI_Status *status)
PRÁCTICA
• Realizar una aplicación de envío y recepción. Se
trata de que el proceso de rango 0 le envíe un dato
numérico introducido por el usuario al proceso de
rango 1 que lo visualizará.
COMUNICACIONES COLECTIVAS
BROADCAST
• Un proceso (maestro) que reparte datos a muchos
(esclavos) y que recopila los resultados que
éstos le proporcionan.
• int MPI_Bcast((…)
• int MPI_Gather(…)
• int MPI_Allgather(…)
COMUNICACIÓN EN PROCESOS
EJERCICIO -> BROADCAST
• Desarrollamos un programa de suma de matrices de
tamaño NxN. El proceso 0 se encargará de generar el
contenido de dos matrices y distribuirlo al resto de
procesos. Cada uno de ellos sumará una columna y el
proceso cero recopilará todos los resultados para
mostrarlos en pantalla. Para que el proceso sea correcto,
el número de procesos lanzados tendrá que ser igual al
rango de las matrices.
• Medios rendimiento de la aplicación. MPI proporciona
un reloj que nos permite medir la duración del cálculo.
• double MPI_Wtime(void)
FUNCIONES DE REPARTO Y REDUCCIÓN
• Una operación de reparto consiste en la distribución de
un conjunto de datos entre una colección de procesos.
A cada proceso le corresponde un subconjunto de los
datos totales.
• La reducción consiste en añadir a la recolección que
vimos en los apartados anteriores una operación a
realizar sobre los datos entrantes, generando con ellos
un resultado final.
• Reparto (envía únicamente una parte del conjunto.) int
MPI_Scatter(…)
• Reducción int MPI_Reduce(…)
Ejercicio 3
En esta práctica se va a programar el producto escalar entre
dos vectores de tamaño cualesquiera:
(x0, x1, …, xn)· (y0, y1, …, yn) = x0·y0 + x1·y1 + … + xn·yn
Se propone construir la aplicación de manera que cada
proceso calcule un término de la suma, por lo que el número
de procesos lanzados debe coincidir con el tamaño de los
vectores. El proceso 0 se encargará de inicializar los arrays
correspondientes a los vectores x e y y de repartir un
elemento a cada proceso. Finalmente el proceso 0 recogerá
las multiplicaciones parciales y mostrará el resultado del
producto escalar, junto con el tiempo empleado.
PROCESOS DE ENTRADA/SALIDA
Serie
int MPI_File_open(…)
Un proceso (el proceso 0) que se encargaba, si era el caso,
de recoger los datos de partida, repartirlos al resto de int MPI_File_set_view(…)
procesos y mostrar los resultados generados.
Especificarle a cada proceso dónde empieza su
Paralelo zona, estructura y tipo de datos
Todos los procesos puedan acceder a un mismo fichero para
int MPI_File_read_at(…)
realizar en él las operaciones de lectura y/o escritura.
• Zona de Archivos int MPI_File_write_at(…)
• Forma de operación (lectura, escritura, creación) int MPI_File_close(…)
Ejercicio 4
Desarrollar un sencillo ejemplo de escritura y posterior
lectura en archivos empleando las funciones de
entrada/salida en paralelo. Consistirá en que los
procesos lanzados escriban en el fichero su rango un
cierto número de veces (definible), uno a continuación
de otro y por orden de rango. Posteriormente cada
proceso leerá del fichero los datos que introdujo y los
mostrará.