proPar Curso 13/14 4 2, 3, 2 2, 2 5 Computadores Paralelos

Slides:



Advertisements
Presentaciones similares
MOVIMIENTO JOVENES DE LA CALLE CIUDAD DE GUATEMALA chi siamo quienes-somos qui sommes-nous who we are attività actividades activités activities scuola.
Advertisements

el 1, el 4 y el 9 tres cuadrados perfectos autosuficientes
Resultado 2.2 con actividad 2.2.1
Paso 1 Portada YO SOY EUROPEO Comisión Europea.
DATSI, FI, UPM José M. Peña Programación en C DATSI, FI, UPM José M. Peña Programación en C.
Computadores de alta velocidad (la lista top500).
Tabla de Contenido Concurrencia.
1 INFORME RESUMEN SOBRE EL NIVEL DE UTILIZACION DE LAS TIC EN LAS EMPRESAS GALLEGAS ( Resumen PYMES ) Noviembre de 2004.
1 INFORME RESUMEN SOBRE EL NIVEL DE UTILIZACION DE LAS TIC EN LAS EMPRESAS GALLEGAS (MICROEMPRESAS, resultados provisionales) 29 de julio de 2004.
AYUDA A LA FUNCIÓN DOCENTE Internet
TEMA 2 MÚLTIPLOS Y DIVISORES
02- PLAN DOCENTE Febrero 2009 SIES – SISTEMA INTEGRADO DE EDUCACIÓN SUPERIOR.
Abstracción de Datos Arrays.
Los Objetos de la Clase Escriban la palabra (the word) en español para los objetos de la clase (#1-20).
CLASE 4 EL ENSAMBLADOR.
NUMBERS
MOVIMIENTO JOVENES DE LA CALLE CIUDAD DE GUATEMALA chi siamo quienes-somos qui sommes-nous who we are attività actividades activités activities alimentazione.
PROGRAMACIÓN PARALELA Tema 3: Rutinas básicas de comunicación
1. Apoyo exterior sobre ala inferior de viga de acero
¿Cuál debe ser el valor de b, para que el número que resulta al reemplazar b en la expresión 5 (b + 2) + 3 sea múltiplo de 5?
Funciones Excel. Parte 1. Introducción 2 Una función Excel es una fórmula o un procedimiento que se realiza en el ambiente de Visual Basic, fuera de.
PROGRAMACIÓN PARALELA Tema 5: Análisis de algoritmos paralelos
Repaso del capítulo Primer Paso
Algoritmos paralelos Lab. 1: Introducción
EL OSO APRENDIZ Y SUS AMIGOS
Programacion de Computadora Prof. Obadiah Oghoerore.
Funciones. Programación, Algoritmos y Estructuras de Datos.
RETIRO DE COMALCALCO DIC. 2012
Proyecto para Centros que trabajan una vez por semana.
Cómputo paralelo usando MPI: Simulaciones de N-cuerpos en la física
RAZONAMIENTO MATEMATICO Mg. CORNELIO GONZALES TORRES
Curso de Programación 1 Plan 97
¡Primero mira fijo a la bruja!
INFORMATICA I Arreglos 1 CLASE 17.
INFORMATICA I Funciones CLASE 13.
ProParCurso 13/14 1Computadores Paralelos 2Programación basada en paso de mensajes 3Técnicas básicas de programación paralela Compulsiva, Divide y Vencerás,
Programación en C (Segunda Parte) DATSI, FI, UPM José M. Peña
Concurrencia en JAVA JAVA es un lenguaje que tiene soporte de concurrencia, mediante Threads. Un thread es un proceso “liviano” (lightweight process) que.
Ismael Camarero1. 2 ¿Qué es un PUNTERO?: Un puntero es un objeto que apunta a otro objeto. Es decir, una variable cuyo valor es la dirección de memoria.
MINIMO COMÚN MÚLTIPLO DE DOS NÚMEROS a y b
Programación Estructurada
CULENDARIO 2007 Para los Patanes.
BEATRIZ LAFONT VILLODRE
Programación con paso de mensajes: MPI
¿Qué es un PUNTERO?: Un puntero es un objeto que apunta a otro objeto. Es decir, una variable cuyo valor es la dirección de memoria de otra variable. No.
El Algoritmo de Floyd Capítulo 6.
Teo. 5: Paradigma "Message Passing"
CI TEORIA semana 8 Subprogramas o funciones Definición de funciones.
Programación I Teoría VI: Recursividad
POO Java Módulo 3 Elementos de programas Identificadores
LOS NÚMEROS.
Slide 7-1 Copyright © 2003 Pearson Education, Inc. Figure: Estructuras de datos.
Clases y objetos La unidad fundamental de programación OO son las clases. Conjunto de métodos y semántica Qué se va a hacer POO Clase: que define la implementación.
Manual de Procedimientos Procedimiento de ejecución del programa de
Algoritmos de ordenación
 2003 Prentice Hall, Inc. All rights reserved. 1 Capítulo 6: Clases y Abstracción de Datos Índice del capítulo 6.1 Introducción 6.2 Estructuras 6.3 Clases.
Semana 5 Subprogramas..
Tres Algoritmos Paralelos para Multiplicación Matriz Vector
MPISistemas Distribuidos1 MPI Un estándar de paso de mensajes para Clusters y Workstations Communications of the ACM, July 1996 J.J. Dongarra, S.W. Otto,
Programación de Memoria Compartida
Comunicación entre Procesos por pase de mensajes Universidad Simón Bolívar Departamento de Computación y T.I Sistemas de operación III CI-4822 Prof. Yudith.
Modelos de Pase de Mensajes
Sistemas Operativos II MC. Daniel Fajardo Delgado INSTITUTO TECNOLÓGICO DE CD. GUZMÁN 30 de Mayo de 2004.
ProParCurso 14/15 1Computadores Paralelos 2Programación basada en paso de mensajes 3Técnicas básicas de programación paralela Compulsiva, Divide y Vencerás,
FUNCIONES Conceptos básicos. Retorno de una función Clases de funciones. Paso de parámetros. Funciones y arrays.
MPI: Message Passing Interface Vera Ortíz Thimoty Duéñez Saúl Moncada Ma. Cristina Otero Carolina teja.
Aitor Viana Sánchez Octavio Hombrados Juan F. Ramos Jesús López Bustos
(agradecimiento: Ruben Weht
INTRODUCCION A M (ESSAGE) P (ASSING) I (NTERFACE) Paradigma de Transferencia de Mensajes Cada procesador corre un programa Todas las variables son privadas.
Transcripción de la presentación:

proPar Curso 13/14 4 2, 3, 2 2, 2 5 Computadores Paralelos Programación basada en paso de mensajes Técnicas básicas de programación paralela Compulsiva, Divide y Vencerás, Pipeline, Síncrona, Equilibrado de carga y Terminación Programación basada en memoria común Algoritmos y aplicaciones Ordenación, …

Procesamiento Paralelo Temario pasoMsj-2 PROGRAMACIÓN BASADA EN PASO DE MENSAJES Recordar concurrencia pthreads: contar y ordenar Un modelo de paso de mensajes Opciones de programación Creación de procesos Rutinas genéricas de paso de mensajes MPI Introducción Procesos Envío y recepción de mensajes Comunicación colectiva Evaluación de programas paralelos Herramientas de depuración y monitorización

proPar Recordar concurrencia pthreads pasoMsj-3 contarPar.c: Número de apariciones de un número en un vector 6 2 0 7 4 9 3 4 9 8 0 6 7 9 6 0 6 7 9 8 6 2 5 2 6 4 7 9 3 5 2 1 7 3 2 6 6 4 4 0 const N = 40; objetivo = 6; numCPUs = 4; var vector array[1..N] of integer; T1 T2 T3 T4 1 3 2 + 8 ¿ Algoritmo paralelo ?

proPar Recordar concurrencia pthreads pasoMsj-4 int longRodaja, numVecesLocal[MAX_ESCLAVOS], *vector; void *esclavo (void *parametro) { ..... } int main (int argc, char *argv[]) { int i, numVeces, cardinalidad = atoi (argv[1]); int numEsclavos = atoi (argv[2]); pthread_t pids[MAX_ESCLAVOS]; // Pedir memoria e inicializar vector // Crear esclavos y esperar a que terminen su trabajo for (i = 0; i < numEsclavos; i++) pthread_create (&pids[i], NULL, esclavo, (void *) i); pthread_join (pids[i], NULL); // Sumar los valores de todos e informar del resultado numVeces = numVecesLocal[0]; for (i = 1; i < numEsclavos; i++) numVeces = numVeces + numVecesLocal[i]; printf (“Veces que aparece = %d\n”, numVeces); } %cuentaPar 1000000 4

proPar Recordar concurrencia pthreads pasoMsj-5 // Variables globales int longRodaja, numVecesLocal[MAX_ESCLAVOS], *vector; void *esclavo (void *parametro) { int yo, inicio, fin, i, j, numVeces; yo = (int) parametro; inicio = yo * longRodaja; fin = inicio + longRodaja; // Buscar en mi parte del vector numVeces = 0; for (i = inicio, i < fin; i++) if (vector[i] == NUM_BUSCADO) numVeces++; numVecesLocal[yo] = numVeces; pthread_exit (NULL); }

proPar Recordar concurrencia pthreads pasoMsj-6 cuentaPar 400.000.000 1..8 // Recorriéndolo diez veces 2 Xeon E5520 Quad 2,26GHz • 8ML3 • 12GB • 500GB Esclavos Tiempo Aceleración Eficiencia 1 5,480 2 2,721 2,01 1,01 4 1,408 3,89 0,97 5 1,286 4,26 0,85 6 1,127 4,86 0,81 7 1,113 4,92 0,70 8 0,998 5,49 0,69

proPar Recordar concurrencia pthreads pasoMsj-7 sortPar.c: Ordenar un vector en memoria ordenar 3 8 15 2 4 1 7 10 6 14 13 5 11 9 12 16 T1 T2 T3 T4 2 3 8 15 1 4 7 10 5 6 13 14 9 11 12 16 T1 T3 mezclar 1 2 3 4 7 8 10 15 5 6 9 11 12 13 14 16 T1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 mezclar

proPar Recordar concurrencia pthreads pasoMsj-8 sortPar.c: Ordenar un vector en memoria [Refinamiento] La mezcla es destructiva => vector auxiliar Va Vb ? A B C D E F G 1 2 3 4 esclavo (yo: integer); ordenarRodaja(yo); case yo of 1: mezclar(A,B,E); mezclar(E,F,G); 2: ; 3: mezclar(C,D,F); 4: ; end; Mezclar requiere haber ordenado … => semáforos

proPar Recordar concurrencia pthreads pasoMsj-9 #define MAX_ENTERO 10000 #define MAX_ESCLAVOS 4 // Solo funciona con 4 esclavos //-------------- VARIABLES GLOBALES ------------------------------- int cardinalidad, longRodaja; int *vector, *vectorBis; sem_t S2a1, S4a3, S3a1; void imprimir (int *vector) { int i; printf ("Contenido del vector\n"); printf ("====================\n"); for (i=0; i<cardinalidad; i++) { printf ("%6d ", vector[i]); if ((i%10) == 0) printf ("\n"); } printf ("\n"); void mezclar (int i, int longRodaja, int *vOrg, int *vDst) { int iDst, iTope, j, jTope; iTope = i + longRodaja; j = iTope; jTope = j + longRodaja; for (iDst = i; iDst < jTope; iDst++) { if (i == iTope ) vDst[iDst] = vOrg[j++]; else if (j == jTope ) vDst[iDst] = vOrg[i++]; else if (vOrg[i] < vOrg[j]) vDst[iDst] = vOrg[i++]; else vDst[iDst] = vOrg[j++];

proPar Recordar concurrencia pthreads pasoMsj-10 void *esclavo(void *parametro) { int yo, inicio, fin, i, j, imenor, menor; int unCuarto, unMedio; yo = (int) parametro; inicio = yo * longRodaja; fin = inicio + longRodaja; unMedio = cardinalidad / 2; unCuarto = cardinalidad / 4; // Ordenar por insercion directa for (i = inicio; i < fin; i++) { imenor = i; menor = vector[i]; for (j = i; j < fin; j++) if (vector[j] < menor) { imenor = j; menor = vector[j]; } vector[imenor] = vector[i]; vector[i] = menor; // Fase de mezclas. Solo valida para 4 esclavos switch (yo) { case 0: sem_wait (&S2a1); mezclar(0, unCuarto, vector, vectorBis); sem_wait (&S3a1); mezclar(0, unMedio, vectorBis, vector); break; case 1: sem_post (&S2a1); break; case 2: sem_wait (&S4a3); mezclar(unMedio, unCuarto, vector, vectorBis); sem_post (&S3a1); break; case 3: sem_post (&S4a3); break; default: printf ("Error\n"); break; pthread_exit(NULL);

proPar Recordar concurrencia pthreads pasoMsj-11 int main( int argc, char *argv[] ) { int i, numEsclavos; pthread_t pids[MAX_ESCLAVOS]; cardinalidad = atoi(argv[1]); numEsclavos = MAX_ESCLAVOS; longRodaja = cardinalidad / numEsclavos; // Pedir memoria e inicializar el vector vector = malloc(cardinalidad * sizeof(int)); vectorBis = malloc(cardinalidad * sizeof(int)); for (i=0; i<cardinalidad; i++) vector[i] = random() % MAX_ENTERO; imprimir(vector); // Inicializar semaforos para sincronizar sem_init (&S2a1, 0, 0); sem_init (&S4a3, 0, 0); sem_init (&S3a1, 0, 0); // Crear esclavos y esperar a que terminen su trabajo for (i=0; i<numEsclavos; i++) pthread_create (&pids[i], NULL, esclavo, (void *) i); pthread_join (pids[i], NULL); return (0); } sort 200000 => 8:350 sortPar 200000 => 2:100

proPar Opciones de programación pasoMsj-12 Entornos de programación paralela en los 90 “Tim Mattson - Intel”

proPar Opciones de programación pasoMsj-13 1 A Pattern Language for Parallel Programming 2 Background and Jargon of Parallel Computing 3 The Finding Concurrency Design Space 4 The Algorithm Structure Design Space 5 The Supporting Structures Design Space 6 The Implementation Mechanisms Design Space 7 A Brief Introduction to OpenMP 8 A Brief Introduction to MPI 9 A Brief Introduction to Concurrent Programming in Java 2005

proPar Opciones de programación pasoMsj-14 Diseño específico de un lenguaje: Occam  Transputer Extensión de lenguaje existente: Fortran M, CC++, Cilk++ www.netlib.org/fortran-m www-unix.mcs.anl.gov/dbpp/text/node51.html www.cilk.com OpenMP Biblioteca de paso de mensajes sobre C, Fortran, C++ PVM: www.csm.ornl.gov/pvm MPI: www-unix.mcs.anl.gov/mpi HPC++: www.extreme.indiana.edu/hpc++/index.html Paralelización automática: El compilador extrae paralelismo del código secuencial ¿ Sistema Operativo ?

proPar Opciones … (TRANSPUTER) pasoMsj-15 1979 Proyecto Europeo: Inmos SGS-Thomson ICL ... † Objetivo: µP de altas prestaciones, como elemento básico para construir máquinas paralelas (multicomputadores) 1992: habían vendido 500.000 unidades (µP+1MB => 180.000pts) Característica relevante: 4 enlaces de comunicación (canales) T800 1 2 3 Ejecución eficiente de n procesos que envían/reciben mensajes por canales P1 P2 P3 cP3 ! dato cP2 ? dato

proPar Opciones… (Placa de desarrollo para PC) pasoMsj-16 TRAM slots Slot 9 IMS C004 Link switch IMS T222 1 2 5 6 4 7 3 8 Tarjeta IMS B008 SubSystem sockets 500.000 pts 1992 PC Bus Interface Slot 0 Slot 1 Slot 2 Slot 9 2 1 2 1 1 3 config reset

proPar Creación de procesos pasoMsj-17 ¿Cómo podría ser contarPar.c si no hay memoria común? maestro 6 2 0 … 0 6 7 … 6 2 5 … 2 1 7 … El vector lo tiene un proceso “maestro” 1 3 2 6 2 0 … 0 6 7 … 6 2 5 … 2 1 7 … + 8 6 2 0 … 0 6 7 … 6 2 5 … 2 1 7 … 1 3 2 esclavo1 esclavo2 esclavo3 esclavo4 2 tipos distintos de procesos El maestro: reparte “envía” trabajo a los “esclavos” y recoge “recibe” resultados

proPar Creación de procesos pasoMsj-18 ¿Cómo podría ejecutarse la aplicación? maestro esclavo1 esclavo2 esclavoN maestro.exe esclavo.exe Un proceso x núcleo M E maestro.c esclavo.c maestro.exe esclavo.exe ¿Arquitecturas distintas? Multiple Program Multiple Data MPMD Dos ejecutables: maestro.exe y esclavo.exe Creación de procesos: estática vs dinámica

proPar Creación de procesos (creación dinámica) pasoMsj-19 MPMD: Multiple Program Multiple Data --------------------------- spawn (“esclavo”, 4, ...) maestro.c contarEnTrozo (......) esclavo.c maestro esclavo %pvm pvm>add PC2 ..... pvm>spawn maestro M E

proPar Creación de procesos (creación estática) pasoMsj-20 SPMD: Single Program Multiple Data --------------------------- if (miIdProceso == 0) maestro() else esclavo() sort.c programa fuente M E 1 8 *.exe %mpirun –np 9 sort %mpirun –p4pg fiConf sort

proPar Creación de procesos pasoMsj-21 A veces, viene bien que el maestro también trabaje esclavo1 esclavo2 esclavo3 maestro0 6 2 0 … 0 6 7 … 6 2 5 … 2 1 7 … 1 3 2 Modelo SPMD y creación de procesos estática

proPar Rutinas genéricas de paso de mensajes pasoMsj-22 Pi.enviar(Pj, &msj, ...)  Pj.recibir(Pi, &msj, ...) --------------------------- enviar (esclavo, &rodaja[k], ...) sortM recibir (maestro, &miRodaja, ...) sortE Máquina PID_Local enviar( Pi, &msj, temporización, )  t Varias semánticas: Bloqueante (Síncrona | Rendezvous) No bloqueante (Asíncrona: Capacidad de almacenar) Temporizada (Tiempo máximo de bloqueo)

proPar Rutinas genéricas de paso de mensajes pasoMsj-23 Bloqueante vs NoBloqueante ¿ Dónde ? ---------- enviar... recibir... ---------- enviar... recibir... Buffer Gestión de buffers El primero se bloquea Transferencia sin buffers adicionales Se sabe que se ha recibido Se desacopla env | rec ¿Se ha recibido? => msjACK enviar( Pi, &msj, temporización, ...)

proPar Rutinas genéricas de paso de mensajes pasoMsj-24 recibirDeCualquiera (&msj) | recibir ( -1, &msj) sortE1 sortEn sortM --------------------------- quien = recibir (-1, &rodaja[k], ...) sortM Mensajes etiquetados Cliente Servidor H P P P P P P P enviar (S, &msj, tipoP) enviar (S, &msj, tipoH) recibir (-1, &msj, tipoH) recibir (-1, &msj, -1 )

proPar Paso de mensajes entre “grupos” pasoMsj-25 Broadcast (a todos) Multicast (a unos concretos) Problema: Número de ocurrencias de (un dato)* en array grande cuentaM cuentaE1 cuentaEn cuentaE2 “Ala” --------------------------- Para todo esclavo enviar (esclavo, &palabra, ...) cuentaM ¿Más eficiente? --------------------------- bcast (esclavos, &palabra, ...) cuentaM

proPar Paso de mensajes entre “grupos” pasoMsj-26 scatter ( esparcir ) y gather ( recoger ) Ej: Ordenación sortM sortE1 sortEn V sortM sortE1 sortEn V scatter (V, rodaja, grupo, emisor, ) sortM y sortE gather (V, rodaja, grupo, receptor, ) sortM y sortE

proPar Paso de mensajes entre “grupos” pasoMsj-27 reduce (recibir de unos concretos y operar) Ej: Ocurrencias cuentaM cuentaE1 2 3 cuentaE2 5 cuentaEn 1 reduce (+, &veces, grupo, receptor, ...) cuentaM y cuentaE + Total = veces; Para todo esclavo recibir (esclavo, &veces, ...) Total += veces; cuentaM máximo, mínimo, *, .....

proPar MPI (Introducción) pasoMsj-28 MPI: Message Passing Interface – 1994 MPI Forum [Nov/92] “Ejecución de aplicaciones paralelas distribuidas en ordenadores heterogéneos” maestro esclavo1 esclavo3 esclavo2 esclavo4 MPI-2 Biblioteca “mpi.h” MPI_Send, MPI_Recv, ------------- Implementación MPICH LAM/MPI IBM, … M E1 E2 E3 E4 Cada uno con su dirIP

proPar MPI (Procesos) pasoMsj-29 Creación estática de procesos (según implementación “mpirun”) 1 3 2 4 MPI_COMM_WORLD >= 0 => MPI_SUCCESS, significado concreto < 0 => un error ( ... MPI_ERR_ARG ...) int MPI_Comm_size(…, int *numProcesos); int MPI_Comm_rank(…, int *yo); int MPI_Finalize(); int MPI_Init( ....... ); /* Inicia MPI */ 5 2 2

proPar MPI (Procesos) pasoMsj-30 helloWorld paralelo #include “mpi.h” int main (int argc, char *argv[]) { int yo, numProcesos; MPI_Init (&argc, &argv); MPI_Comm_size (MPI_COMM_WORLD, &numProcesos); MPI_Comm_rank (MPI_COMM_WORLD, &yo); if (yo == 0) printf (“Creados %d procesos\n”, numProcesos); printf (“Hola, soy el proceso %d\n”, yo); MPI_Finalize(); } % mpirun –np 3 helloWorld % mpirun –p4pg helloWorld.txt helloWorld pc1 2 /usuarios/alumnosPropar/propar01/p1/helloWorld pc2 2 /usuarios/alumnosPropar/propar01/p1/helloWorld pc3 1 /usuarios/alumnosPropar/propar01/p1/holaMundo

proPar MPI (Envío y Recepción Simple) pasoMsj-31 Enviar y recibir arrays de datos simples (int, byte, ...) Bloqueante P1 P2 int vector[N]; ---------- MPI_Send (vector, … P2, ...) int tabla[M]; ---------- MPI_Recv (tabla, … P1, ...) int MPI_Send(void *buffer, int cuantos, MPI_Datatype tipo, int destino, int etiqueta, MPI_Comm grupo) MPI_INT, MPI_FLOAT, … MPI_COMM_WORLD 0..MPI_TAG_UB

proPar MPI (Envío y Recepción Simple) pasoMsj-32 Enviar y recibir arrays de datos simples (int, byte, ...) Bloqueante int MPI_Recv(void *buffer, int cuantos, MPI_Datatype tipo, int remitente,int etiqueta,MPI_Comm grupo, MPI_Status *estado) MPI_ANY_SOURCE MPI_ANY_TAG estado.MPI_SOURCE estado.MPI_TAG int MPI_Get_count( MPI_Status *estado, MPI_Datatype tipo, int *cuantos)

proPar MPI (Envío y Recepción Simple) pasoMsj-33 Ejemplo de uso: psendrec.c #include <stdio.h> #include <unistd.h> #include “mpi.h" #define N 3 #define VECES 5 void esclavo(void) {...} void maestro(void) {...} int main( int argc, char *argv[] ) { int yo; MPI_Init (&argc, &argv); MPI_Comm_rank (MPI_COMM_WORLD, &yo); if (yo == 0) maestro(); else esclavo(); MPI_Finalize(); return 0; }

proPar MPI (Envío y Recepción Simple) pasoMsj-34 Ejemplo de uso: psendrec.c void maestro (void) { int i, j, vector[N]; for (i=0; i<VECES; i++) { printf ("M: envia => "); for (j=0; j<N; j++) { vector[j] = i*N+j; printf("%d ", vector[j]); } printf ("\n"); MPI_Send (vector, N, MPI_INT, 1, 1, MPI_COMM_WORLD); esclavo

proPar MPI (Envío y Recepción Simple) pasoMsj-35 Ejemplo de uso: psendrec.c void esclavo(void) { int i, j,tabla[N], n; MPI_Status estado; sleep(2); for (i=0; i<VECES; i++) { MPI_Recv (tabla, N, MPI_INT, 0, 1, MPI_COMM_WORLD, &estado); MPI_Get_count (&estado, MPI_INT, &n); printf ("E: recibe => "); for (j=0; j<N; j++) printf("%d ", tabla[j]); printf (" de tid = %d eti = %d longi = %d\n", estado.MPI_SOURCE, estado.MPI_TAG, n); } maestro

proPar MPI (Envío y Recepción No Tan Simple) pasoMsj-36 Enviar y recibir arrays de datos simples No Bloqueante int MPI_Iprobe(int origen, int etiqueta, MPI_Comm grupo, int *hayMsj, MPI_Status *estado) Hacer otras cosas NO int MPI_Recv(void *buffer,… MPI_Status *estado) SI Enviar y recibir datos no homogéneos Crear tipos => Algo tedioso

proPar MPI (Comunicación colectiva) pasoMsj-37 cuenta.0 cuenta.1 cuenta.N cuenta.2 “Ala” int MPI_Bcast(void *buffer, int cuantos, MPI_Datatype tipo, int emisor, MPI_Comm grupo) Send+Recv ? tag void maestro () { void esclavo () { char palabra[4]; char texto[4]; ---------- ---------- MPI_Bcast ( MPI_Bcast ( palabra, 4, MPI_CHAR, texto, 4, MPI_CHAR, 0, MPI_COMM_WORLD); 0, MPI_COMM_WORLD);

proPar MPI (Comunicación colectiva) pasoMsj-38 sendCount int MPI_Scatter( void *vOrg, int nOrg, MPI_Datatype tOrg, void *vDst, int nDst, MPI_Datatype tDst, int emisor, MPI_Comm grupo); grupoE.1 grupoE.9 grupoM.0 + MPI_SUM, MPI_PROD, MPI_MIN, MPI_MAX, .... int MPI_Reduce(void *vOrg, void *vDst, int nOrg, MPI_Datatype tDatoOrg, int operacion, int receptor, MPI_Comm grupo);

proPar MPI (Comunicación colectiva: Ejemplo) pasoMsj-39 Ejemplo de uso completo: cuentaPar2.c (modelo SPMD) #include <stdio.h> #include “mpi.h" #define CARDINALIDAD 2000000 #define MAX_ENTERO 1000 #define NUM_BUSCADO 5 int main( int argc, char *argv[] ) { int i, numVeces, numVecesTotal, yo; int longRodaja, numProcesos; int *vector; MPI_Init (&argc, &argv); MPI_Comm_size (MPI_COMM_WORLD, &numProcesos); MPI_Comm_rank (MPI_COMM_WORLD, &yo); --------------------------- MPI_Finalize(); }

proPar MPI (Comunicación colectiva: Ejemplo) pasoMsj-40 Ejemplo de uso completo: cuentaPar2.c // Pedir memoria vector e inicializarlo si maestro longRodaja = CARDINALIDAD / numProcesos; if (yo == 0) { vector = malloc (CARDINALIDAD * 4); for (i=0; i<CARDINALIDAD; i++) vector[i] = random() % MAX_ENTERO; } else vector = malloc (longRodaja * 4); MPI_Scatter (vector, longRodaja, MPI_INT, vector, longRodaja, MPI_INT, 0, MPI_COMM_WORLD); // Todos buscan en su trozo numVeces = 0; for (i=0; i<longRodaja; i++) if (vector[i] == NUM_BUSCADO) numVeces++; MPI_Reduce (&numVeces, &numVecesTotal, 1, MPI_INT, MPI_SUM, 0 , MPI_COMM_WORLD); if (yo == 0) printf (“Numero de veces => %d\n”, numVecesTotal);

proPar MPI (Comunicación colectiva) pasoMsj-41 Otras llamadas interesantes: int MPI_Gather(void *vOrg, int nOrg, MPI_Datatype tOrg, void *vDst, int nDst, MPI_Datatype tDst, int receptor, MPI_Comm grupo); int MPI_Barrier(MPI_Comm grupo); ---------- MPI_Comm_size (MPI_COMM_WORLD, &numProcesos); // Computar todos paso 1 MPI_Barrier (MPI_COMM_WORLD); // Computar todos paso 2 6

proPar Evaluación de programas paralelos pasoMsj-42 ¿Cuánto tardará mi programa paralelo TP? Medición experimental Estudio analítico Codificar, Depurar, Probar, ... Modelo imperfecto, aproximado N’ N TP = TCPU + TRED m e0 e9 cuentaVeces: V[1.000.000] 10 esclavos Enviar rodajas TRED Recibir veces TRED veces = 0; for (i=0; i<N’; i++) if (rodaja[i] == D) veces++; Contar veces TCPU N’ * (#i * Tinst) O (N) | O (N2) | O (NlogN) | O(logN)

proPar Evaluación de programas paralelos pasoMsj-43 TP = TCPU + TRED N’ * (#i * Tinst) #d t TL #msj, tamaño(#d), topología red, tecnología, ... #m * (TL + #d * TD) Ejemplos T3D+PVM IBM PS2+MPI iacluster+MPI 40s 35s 3s TL 64ns 230ns 63ns TD[8B] 0,6ns 4,2ns 11ns Tinst 66666 8333 273 TL 107 55 6 TD 1 Tinst Normalizar Solapar tiempos | ocultar latencias Comunicación asíncrona TP = TCPU + TRED

proPar Evaluación de programas paralelos pasoMsj-44 Ejemplo: cuentaVeces, V[1.000.000], 10 esclavos T1 = 1.000.000 * (#i * Tinst) T10 = TRED(10Rodajas) + TCPU(100.000) + TRED(10Resultados) T3D: TL(273) y TD(6) T10 = 10*(273+100.000*6) + 100.000*#i*1 + 10*(273+6) = 6.005.520 + 100.000#i S10 = 1.000.000*#i / (6.005.520+100.000#i) #i S10 5 0,8 10 1,4 500 8,9 iacluster: TL(66.666) y TD(64) T10 = ... 66.666 ... 64 + ...*1 + ... 66.666+64 = 65.333.960 + 100.000#i S10 = 1.000.000*#i / (65.333.960 +100.000#i) #i S10 50 0,71 100 1,33 500 4,34

proPar Herramientas de depuración y monitorización pasoMsj-45 Medición de tiempos de ejecución Depuración Monitorización #include <sys/time.h> struct timeval t0, tf, tiempo; /* Inicialización */ gettimeofday (&t0, NULL); /* ejecucion del programa paralelo */ gettimeofday (&tf, NULL); timersub (&tf, &t0, &tiempo); printf (“Tiempo => %ld:%ld seg:micro\n”, tiempo.tv_sec, tiempo.tv_usec); ¿Efecto del optimizador de código? gcc –O3 Evitar E/S

proPar Herramientas de depuración y monitorización pasoMsj-46 %mpirun –dbg=ddd –np 2 psendrec depurar (ddd) printf fflush(stdout) setbuf(stdout, NULL) Depurar más de un proceso, algo más complejo

proPar Herramientas de depuración y monitorización pasoMsj-47 Monitorización (XPVM) para PVM

proPar Herramientas de depuración y monitorización pasoMsj-48 Monitorización (totalview) para MPI, openMP, … www.etnus.com FIN