Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
Introducción a la Computación Heterogénea
Carlos Bederián, Nicolás Wolovick
FaMAF, Universidad Nacional de Córdoba, Argentina
18 de Febrero de 2013
[email protected]
Revisión 3857, 2013-02-18
Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
Qué
Computación Heterogénea
Uso de varios tipos de unidades de cómputo.
Nuestro contexto será el de High Performance Computing (HPC).
Al TOP500/Nov2012 liderado por una computadora híbrida.
= AMD Opteron 6274 + NVIDIA Kepler K20X
Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
Por qué
Nos gustan las GPUs
+ Buenos GFLOPS/Watt, GFLOPS/$.
+ Solución adecuada para presupuestos acotados.
– Requieren de entrenamiento específico:
ECAR13 (Jul13), WHPC13 (May13), RIO2013 (Fer13),
SEAGPGPU (Sep12), ECAR12 (Jul12), RIO2012 (Feb12),
PEAGPGPU (May11).
Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
Por qué
Nos gustan las GPUs
+ Buenos GFLOPS/Watt, GFLOPS/$.
+ Solución adecuada para presupuestos acotados.
– Requieren de entrenamiento específico:
ECAR13 (Jul13), WHPC13 (May13), RIO2013 (Fer13),
SEAGPGPU (Sep12), ECAR12 (Jul12), RIO2012 (Feb12),
PEAGPGPU (May11).
Ahora queremos escalar a muchas GPUs.
Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
Cómo
Mezcla de:
MPI Open standard para biblioteca de comunicación entre
procesos (MPI Forum)
CUDA Modelo de programación + arquitectura de cómputo
(NVIDIA)
Dos modelos distintos.
Vamos a remarcar sus aspectos comunes.
Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
Quienes somos
GPGPU Computing Group en FaMAF–UNC
Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
Esquema del curso
Lun18 MPI
Mar19 CUDA
Jue21 MPI+CUDA
Vie22 Comunicación directa
Teóricos 11:00 a 13:30
Laboratorios 15:00 a 17:00?
Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
Como aprovechar el curso
Tener un cliente con mucha necesidad de cómputo:
• Computólogo buscando bugs en programas grandes.
• Físico explorando propiedades ferromagnéticas.
• Químico analizando dinámica molecular.
• Biólogo simulando comunidades de hormigas.
• . . .
Estamos haciendo HPC aplicado.
Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
Modelo de paralelismo
Es Single Program, Multiple Data (SPMD).
Idem al fork() de UNIX.
pid = fork();
if (pid == 0) {
/* Codigo del hijo */
} else {
/* Codigo del padre */
}
• Clon del proceso.
• Se distingue por un id.
• Memoria disjunta.
• Comunicación por mensajes (típicamente vía FS).
Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
Uso de fork()
#include <stdio.h> /* printf() */
#include <unistd.h> /* fork() */
#include <sys/types.h> /* pid_t */
#include <stdlib.h> /* getpid() */
#include <sys/wait.h>
#include <assert.h>
int main(int argc, char **argv)
{
unsigned int i = 0, h = 0;
pid_t s = 0;
int status = 0;
assert(2==argc);
h = atoi(argv[1]);
for (i = 0; i < h; ++i) {
s = fork();
if (0 == s) {
printf("Hijo (pid) %5d\n", getpid());
return 0; /* no quiero nietos */
}
}
for (i = 0; i < h; ++i) {
s = wait(&status);
assert(0 <= s);
}
return 0;
}
Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
Algo similar en MPI
#include <stdio.h> /* printf() */
#include <mpi.h>
int main(int argc, char **argv)
{
int size = 0, rank = 0;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
printf("Hijo %2d\n", rank);
MPI_Finalize();
return 0;
}
• La cantidad y el lanzamiento de los procesos es externo.
• Todo el código ejecuta en procesos disjuntos.
Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
Ejecución
-o fork_n
-o hello
fork_n.c
hello.c
nicolasw@plata:~/IntroHeteroRio2013/Slides/Clase1/src$ make
mpicc -O3 -Wall -Wextra -Werror -lmpi
mpicc -O3 -Wall -Wextra -Werror -lmpi
nicolasw@plata:~/IntroHeteroRio2013/Slides/Clase1/src$ time ./fork_n 8
Hijo (pid) 29367
Hijo (pid) 29371
Hijo (pid) 29370
Hijo (pid) 29374
Hijo (pid) 29369
Hijo (pid) 29368
Hijo (pid) 29373
Hijo (pid) 29372
0m0.007s
0m0.004s
real
user
sys 0m0.000s
nicolasw@plata:~/IntroHeteroRio2013/Slides/Clase1/src$ time mpiexec -np 8 ./hello
Hijo 3
Hijo 1
Hijo 5
Hijo 4
Hijo 0
Hijo 6
Hijo 2
Hijo 7
real
user
sys 0m0.096s
0m1.121s
0m0.072s
Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
Corriendo los ejemplos – 2
Notamos
• Compilación y ejecución de MPI.
(mpicc, mpiexec)
• No-determinismo.
• Tiempos de ejecución muy diferentes.
(overhead de lanzamiento)
Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
¿Para qué sirve MPI?
Utilizar hardware paralelo
• Multicore.
• Clusters multicore.
Unifica programación de
dispositivos de:
• Memoria compartida
(multicore).
• Pasaje de mensajes
(cluster).
Cluster mendieta:
8×(2×Xeon E5 2680 + 2×Tesla m2090 + IB QDR + 2×GigE)
Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
Complejidad de un nodo
Un solo nodo puede tener una
red interna.
Es ccNUMA, luego las
consideraciones son de eficiencia
y no de corrección.
Cada nodo se interconecta con
una o varias redes externas.
MPI abstrae estas complejidades.
Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
Mensaje punto-a-punto
Partes
• Cabecera
• Remitente: número de proceso, ó MPI_ANY_SOURCE.
• Destinatario: número de proceso ó MPI_PROC_NULL.
• Etiqueta: identificador numérico, ó MPI_ANY_TAG.
• Tipo de dato: (ver tabla)
• Grupo de comunicación: handle a un comunicador,
ó MPI_COMM_WORLD.
• Datos
Es como un IP frame, pero contiene información sobre los datos
que transporta.
Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
Predefinidos
Tipos de datos
MPI
MPI_FLOAT
MPI_INT
MPI_DOUBLE
MPI_CHAR
. . .
C
float
int
double
char
. . .
Los tipos de datos atacan dos problemas:
• Heterogeneidad en las representaciones.
(little/big endian, tamaño, representaciones punto flotante fp)
• Irregularidad y no-contiguidad en los datos.
(estructuras, strided access)
Hay tipos de datos definidos por el usuario (structs y strided).
Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
Enviar y recibir
int MPI_Send(void *sbuf,
/* in */
int scount,
/* in */
MPI_Datatype sdatatype, /* in */
int sdest,
/* in */
int stag,
/* in */
MPI_Comm scomm)
/* in */
int MPI_Recv(void *rbuf,
/* out */
int rcount,
/* in */
MPI_Datatype rdatatype, /* in */
int rsource,
/* in */
int rtag,
/* in */
MPI_Comm rcomm,
/* in */
MPI_Status *rstatus)
/* out */
Message matching
scount ≤ rcount ?
rdatatype = sdatatype
rsource =srank
sdest =rrank
rtag = stag
rcomm = scomm
• rstatus->{MPI_SOURCE, MPI_TAG, MPI_ERROR}.
• Se puede mantener scopes disjuntos de comunicación con
• Un mínimo de type-checking con tag.
• Lo recibido puede ser menos que rcount:
{r,s}comm.
MPI_Get_count(rstatus, rdatatype, &actual_count).
Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
¿Sincrónico o asincrónico?
rank=0
MPI_Send(buf, size, MPI_CHAR, 1, 33, MPI_COMM_WORLD);
MPI_Recv(buf, size, MPI_CHAR, 1, 34, MPI_COMM_WORLD, &status);
rank=1
MPI_Send(buf, size, MPI_CHAR, 0, 34, MPI_COMM_WORLD);
MPI_Recv(buf, size, MPI_CHAR, 0, 33, MPI_COMM_WORLD, &status);
¿Funciona?
Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
¿Sincrónico o asincrónico?
rank=0
MPI_Send(buf, size, MPI_CHAR, 1, 33, MPI_COMM_WORLD);
MPI_Recv(buf, size, MPI_CHAR, 1, 34, MPI_COMM_WORLD, &status);
rank=1
MPI_Send(buf, size, MPI_CHAR, 0, 34, MPI_COMM_WORLD);
MPI_Recv(buf, size, MPI_CHAR, 0, 33, MPI_COMM_WORLD, &status);
¿Funciona?
So, Ni.
Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
¿Sincrónico o asincrónico? – 2
#include <stdio.h> /* printf() */
#include <stdlib.h> /* malloc() */
#include <string.h> /* memset() */
#include <assert.h>
#include <mpi.h>
int main(int argc, char **argv)
{
const int MAX_LOG_SIZE = 19;
int i = 0;
int size = 0, rank = 0;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
assert(2 == size); /* par de procesos */
for (i = 1; i < MAX_LOG_SIZE; ++i) {
int buf_size = (1<<i);
char *buf = malloc(buf_size);
assert(buf != NULL);
memset(buf, rank, buf_size);
MPI_Send(buf, buf_size, MPI_CHAR, 1-rank, (2-rank)*i, MPI_COMM_WORLD);
printf("%i: iter %i sent %i byte(s)\n", rank, i, buf_size);
MPI_Recv(buf, buf_size, MPI_CHAR, 1-rank, (rank+1)*i, MPI_COMM_WORLD, &status);
assert(buf[buf_size/2] == 1-rank); /* correccion => esto */
printf("%i: iter %i recv %i byte(s)\n", rank, i, buf_size);
free(buf); buf = NULL;
}
MPI_Finalize();
return 0;
Motivación
Intro
P2P
Grupal
Comm&topo
Superposición comm&comp
Ejemplo
Fin
¿Sincrónico o asincrónico? – 3
nicolasw@plata:~/IntroHeteroRio2013/Slides/Clase1/src$ mpiexec -np 2 ./buffering
0: iter 1 sent 2 byte(s)
0: iter 1 recv 2 byte(s)
1: iter 1 sent 2 byte(s)
0: iter 2 sent 4 byte(s)
1: iter 1 recv 2 byte(s)
1: it
Comentarios de: Introducción a la Computación Heterogénea (0)
No hay comentarios