La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

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,

Presentaciones similares


Presentación del tema: "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,"— Transcripción de la presentación:

1 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, Pipeline, Síncrona, Equilibrado de carga y Terminación 4Programación basada en memoria común 5Algoritmos y aplicaciones Ordenación, … 4 4 2, 3, 2 2, 2 5 4

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

3 proParRecordar concurrencia pthreadspasoMsj-3 contarPar.c: Número de apariciones de un número en un vector const N = 40; objetivo = 6; numCPUs = 4; var vector array[1..N] of integer; ¿ Algoritmo paralelo ? T1T1 T2T2 T3T3 T4T

4 proPar Recordar concurrencia pthreadspasoMsj-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); for (i = 0; i < numEsclavos; 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

5 proPar Recordar concurrencia pthreadspasoMsj-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); }

6 proPar Recordar concurrencia pthreadspasoMsj-6 51,2864,260,85 61,1274,860,81 71,1134,920,70 80,9985,490,69 EsclavosTiempoAceleraciónEficiencia 15,480 22,7212,011,01 41,4083,890,97 cuentaPar // Recorriéndolo diez veces 2 Xeon E5520 Quad 2,26GHz 8ML3 12GB 500GB

7 proParRecordar concurrencia pthreadspasoMsj-7 sortPar.c: Ordenar un vector en memoria T1T1 T2T2 T3T3 T4T ordenar T1T1 T3T3 mezclar T1T mezclar

8 proParRecordar concurrencia pthreadspasoMsj-8 sortPar.c: Ordenar un vector en memoria [Refinamiento] ABCD EF G 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; ? 1.La mezcla es destructiva => vector auxiliar Va Vb Va 2Mezclar requiere haber ordenado … => semáforos

9 proPar Recordar concurrencia pthreadspasoMsj-9 #define MAX_ENTERO #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

10 proPar Recordar concurrencia pthreadspasoMsj-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); }

11 proPar Recordar concurrencia pthreadspasoMsj-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 8:350 sortPar => 2:100

12 proParOpciones de programaciónpasoMsj-12 Entornos de programación paralela en los 90 Tim Mattson - Intel

13 proParOpciones de programaciónpasoMsj-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

14 proParOpciones de programaciónpasoMsj-14 1.Diseño específico de un lenguaje: Occam Transputer 2.Extensión de lenguaje existente: Fortran M, CC++, Cilk++ www-unix.mcs.anl.gov/dbpp/text/node51.html 3.Biblioteca de paso de mensajes sobre C, Fortran, C++ PVM: MPI: www-unix.mcs.anl.gov/mpi HPC++: Paralelización automática: El compilador extrae paralelismo del código secuencial ¿ Sistema Operativo ? OpenMP

15 1979 Proyecto Europeo: InmosSGS-Thomson ICL... Objetivo:µP de altas prestaciones, como elemento básico para construir máquinas paralelas (multicomputadores) 1992: habían vendido unidades (µP+1MB => pts) Característica relevante: 4 enlaces de comunicación (canales) T Ejecución eficiente de n procesos que envían/reciben mensajes por canales P1P1 P2P2 P3P3 proPar Opciones … (TRANSPUTER)pasoMsj-15 cP3 ! datocP2 ? dato

16 TRAM slots Slot 9 IMS C004 Link switch IMS T Tarjeta IMS B008 SubSystem sockets PC Bus Interface Slot 0Slot 1Slot 2Slot config reset pts 1992 proPar Opciones… (Placa de desarrollo para PC)pasoMsj-16

17 proParCreación de procesospasoMsj-17 ¿Cómo podría ser contarPar.c si no hay memoria común? …0 6 7 …6 2 5 …2 1 7 … + 8 esclavo1esclavo2esclavo3esclavo4 maestro …0 6 7 …6 2 5 …2 1 7 … El vector lo tiene un proceso maestro El maestro:reparte envía trabajo a los esclavos y recoge recibe resultados …0 6 7 …6 2 5 …2 1 7 … tipos distintos de procesos

18 proParCreación de procesospasoMsj-18 ¿Cómo podría ejecutarse la aplicación? maestro esclavo1esclavo2esclavoN Un proceso x núcleo MEEE Dos ejecutables: maestro.exe y esclavo.exe maestro.cesclavo.c maestro.exeesclavo.exe Multiple Program Multiple Data MPMD maestro.exeesclavo.exe Creación de procesos: estática vs dinámica ¿Arquitecturas distintas?

19 proParCreación de procesos (creación dinámica)pasoMsj-19 MPMD: Multiple Program Multiple Data spawn (esclavo, 4,...) maestro.c contarEnTrozo (......) esclavo.c maestroesclavo %pvm pvm>add PC pvm>spawn maestro M EE

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

21 proParCreación de procesospasoMsj-21 A veces, viene bien que el maestro también trabaje esclavo1esclavo2esclavo3 maestro …0 6 7 …6 2 5 …2 1 7 … …6 2 5 …2 1 7 … Modelo SPMD y creación de procesos estática

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

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

24 proParRutinas genéricas de paso de mensajespasoMsj-24 recibirDeCualquiera (&msj) | recibir ( -1, &msj) sortE1sortEn sortM quien = recibir (-1, &rodaja[k],...) sortM Mensajes etiquetados PPPPPPPH enviar (S, &msj, tipoP) enviar (S, &msj, tipoH) recibir (-1, &msj, tipoH) recibir (-1, &msj, -1 ) ClienteServidor Cliente

25 proParPaso de mensajes entre grupospasoMsj-25 Broadcast (a todos) Multicast (a unos concretos) Para todo esclavo enviar (esclavo, &palabra,...) cuentaM Problema: Número de ocurrencias de (un dato)* en array grande cuentaM cuentaE1cuentaEncuentaE2 Ala bcast (esclavos, &palabra,...) cuentaM ¿Más eficiente?

26 sortM sortE1sortEn V sortM sortE1sortEn V proParPaso de mensajes entre grupospasoMsj-26 scatter ( esparcir ) y gather ( recoger ) Ej: Ordenación scatter (V, rodaja, grupo, emisor, ) sortM y sortE gather (V, rodaja, grupo, receptor, ) sortM y sortE

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

28 proParMPI (Introducción)pasoMsj-28 MPI: Message Passing Interface – 1994 MPI Forum [Nov/92] Ejecución de aplicaciones paralelas distribuidas en ordenadores heterogéneos maestro esclavo1esclavo3esclavo2esclavo4 Cada uno con su dirIP Biblioteca mpi.h MPI_Send, MPI_Recv, ME1E2E3E4 Implementación MPICH LAM/MPI IBM, … MPI-2

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

30 proParMPI (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

31 proParMPI (Envío y Recepción Simple)pasoMsj-31 Enviar y recibir arrays de datos simples (int, byte,...) Bloqueante int vector[N]; MPI_Send (vector, … P2,...) P1 int tabla[M]; MPI_Recv (tabla, … P1,...) P2 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

32 proParMPI (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) estado.MPI_SOURCE estado.MPI_TAG MPI_ANY_SOURCE MPI_ANY_TAG int MPI_Get_count( MPI_Status *estado, MPI_Datatype tipo, int *cuantos)

33 proParMPI (Envío y Recepción Simple)pasoMsj-33 Ejemplo de uso: psendrec.c #include #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; }

34 proParMPI (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 "); for (j=0; j

35 proParMPI (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 "); for (j=0; j

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

37 proParMPI (Comunicación colectiva)pasoMsj-37 int MPI_Bcast(void *buffer, int cuantos, MPI_Datatype tipo, int emisor, MPI_Comm grupo) cuenta.0 cuenta.1cuenta.Ncuenta.2 Ala 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); ? tag Send+Recv

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

39 proParMPI (Comunicación colectiva: Ejemplo)pasoMsj-39 Ejemplo de uso completo: cuentaPar2.c (modelo SPMD) #include #include mpi.h" #define CARDINALIDAD #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(); }

40 proParMPI (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 %d\n, numVecesTotal);

41 proParMPI (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

42 proParEvaluación de programas paralelospasoMsj-42 ¿Cuánto tardará mi programa paralelo T P ? Medición experimental Estudio analítico Codificar, Depurar, Probar,... Modelo imperfecto, aproximado m e0e9 cuentaVeces: V[ ] 10 esclavos T P = T CPU + T RED a.Enviar rodajasT RED c.Recibir vecesT RED b.Contar vecesT CPU veces = 0; for (i=0; i

43 proParEvaluación de programas paralelospasoMsj-43 #m * (T L + #d * T D ) #d t TLTL T P = T CPU + T RED N * (#i * T inst ) Ejemplos T3D+PVM IBM PS2+MPI iacluster+MPI 40 s 35 s 3 s TLTL 64ns 230ns 63ns T D[8B] 0,6ns 4,2ns 11ns T inst TLTL TDTD T inst Normalizar T P = T CPU + T RED Solapar tiempos | ocultar latencias Comunicación asíncrona #msj, tamaño(#d), topología red, tecnología,...

44 proParEvaluación de programas paralelospasoMsj-44 Ejemplo: cuentaVeces, V[ ], 10 esclavos T 1 = * (#i * T inst ) T 10 = T RED (10Rodajas) + T CPU ( ) + T RED (10Resultados) T3D: T L (273) y T D (6) T 10 = 10*( *6) *#i*1 + 10*(273+6) = #i S 10 = *#i / ( #i) iacluster: T L (66.666) y T D (64) T 10 = * = #i S 10 = *#i / ( #i) #iS , , ,34 #iS ,8 101,4 5008,9

45 proParHerramientas de depuración y monitorizaciónpasoMsj-45 Medición de tiempos de ejecución Depuración Monitorización #include 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); Evitar E/S ¿Efecto del optimizador de código? gcc –O3

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

47 proParHerramientas de depuración y monitorizaciónpasoMsj-47 Monitorización (XPVM) para PVM

48 proParHerramientas de depuración y monitorizaciónpasoMsj-48 Monitorización (totalview) para MPI, openMP, … FIN


Descargar ppt "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,"

Presentaciones similares


Anuncios Google