Este documento presenta la Unidad 4 de un curso sobre Aplicaciones Distribuidas. La unidad cubre conceptos de programación paralela y distribuida utilizando OpenMP y MPI. Incluye información sobre programación de memoria compartida y distribuida, modelos de programación paralela, y ejemplos de código para desarrollar aplicaciones paralelas y distribuidas.
POE Unidad 3: Aplicaciones visuales orientadas a eventos con acceso a base de...
Programación paralela y distribuida con OpenMP y MPI
1. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 1
30/01/2023
Programación paralela y
distribuida
Unidad 4
Material docente compilado por el profesor Ph.D. Franklin Parrales Bravo
para uso de los cursos de Aplciaciones Distribuidas
2. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 2
30/01/2023
Objetivo general de la Unidad 4
Aplicar los conceptos, lenguajes de programación,
plataformas y herramientas de la computación
paralela y distribuida para el desarrollo de
aplicaciones distribuidas.
3. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 3
30/01/2023
Unidad 4: Programación paralela y
distribuida
• Interfaz de programación de aplicaciones OpenMP y
de paso de mensajes MPI
• Programación multiproceso de memoria compartida
– Desarrollo de programas con OpenMP
– Modelo de programación paralela
• Programación concurrente y distribuida.
– High Performance Computing
– Interfaz de paso de Mensajes MPI
– Desarrollo de programas con MPI
• Desarrollo de programas distribuidos.
4. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 4
30/01/2023
Paso de mensajes vs. memoria compartida
• Paso de mensajes: intercambiar datos
explícitamente a través de IPC
• Los desarrolladores de aplicaciones
definen el protocolo y el formato de
intercambio, el número de
participantes y cada intercambio
• Memoria compartida: todos los
procesadores comparten datos a través
de la memoria
• Las aplicaciones deben ubicar y
mapear regiones de memoria
compartida para intercambiar datos
Cliente
send(msg)
MSG
Cliente
recv(msg)
MSG
MSG IPC
Cliente
send(msg)
Cliente
recv(msg)
Memoria
compartida
5. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 5
30/01/2023
OpenMP
• Una extensión de lenguaje con construcciones
para programación paralela:
– Secciones críticas, acceso atómico, variables
privadas, barreras
• La paralelización es ortogonal a la funcionalidad.
– Si el compilador no reconoce las directivas de
OpenMP, el código permanece funcional (aunque de
un solo subproceso).
• Estándar de la industria: compatible con Intel,
Microsoft, IBM, HP
6. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 6
30/01/2023
OpenMP execution model
• Fork and Join: el thread maestro genera un
equipo de threads según sea necesario
Master thread
Master thread
Worker
Thread
FORK
JOIN
FORK
JOIN
Regiones
paralelas
7. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 7
30/01/2023
MPI
• MPI - Message Passing Interface
– Estándar de biblioteca definido por un comité de
proveedores, implementadores y programadores
paralelos
– Se utiliza para crear programas paralelos basados en
el paso de mensajes.
• Portable: un estándar, muchas implementaciones
– Disponible en casi todas las máquinas paralelas en C
y Fortran
– Plataforma estándar de facto para la comunidad HPC
8. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 8
30/01/2023
Grupos, comunicadores, contextos
• Grupo: un conjunto ordenado fijo de
k procesos, i.e., 0, 1, .., k-1
• Comunicador: especificar el alcance
de la comunicación
– Entre procesos en un grupo
– Entre dos grupos disjuntos
• Contexto: partición del espacio de
comunicación
– Un mensaje enviado en un contexto no
se puede recibir en otro contexto
Esta imagen ha sido tomada de:
“Writing Message Passing Parallel Programs
with MPI”, Course Notes, Edinburgh Parallel
Computing Centre
The University of Edinburgh
9. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 9
30/01/2023
Paso de mensajes síncrono vs. asíncrono
• Una comunicación síncrona no se
completa hasta que el mensaje ha sido
recibido
• Una comunicación asíncrona se completa
antes de que se reciba el mensaje
10. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 10
30/01/2023
Modos de comunicación
• Síncrono: se completa una vez que el remitente recibe el
acuse de recibo
• Asíncrono: 3 modos
– Standard send: se completa una vez que se ha enviado el
mensaje, lo que puede implicar o no que el mensaje ha
llegado a su destino
– Buffered send: se completa inmediatamente, si el receptor
no está listo, MPI almacena el mensaje localmente
– Ready send: se completa de inmediato, si el receptor está
listo para recibir el mensaje, lo recibirá; de lo contrario, el
mensaje se descartará en silencio
11. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 11
30/01/2023
Bloqueante vs. No bloqueante
• Bloqueante, significa que el programa no
continuará hasta que se complete la
comunicación
– Comunicación síncrona
– Barreras: esperar a que todos los procesos del
grupo lleguen a un punto de ejecución
• No bloqueante, significa que el programa
continuará, sin esperar a que se complete la
comunicación
12. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 12
30/01/2023
Unidad 4: Programación paralela y
distribuida
• Interfaz de programación de aplicaciones OpenMP y
de paso de mensajes MPI
• Programación multiproceso de memoria compartida
– Desarrollo de programas con OpenMP
– Modelo de programación paralela
• Programación concurrente y distribuida.
– High Performance Computing
– Interfaz de paso de Mensajes MPI
– Desarrollo de programas con MPI
• Desarrollo de programas distribuidos.
13. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 13
30/01/2023
Programación multiproceso de
memoria compartida
El modelo de memoria utilizado hace que la
programación de aplicaciones paralelas para cada
caso sea esencialmente diferente.
Los sistemas paralelos MIMD presentan dos
arquitecturas diferenciadas: memoria compartida
y memoria distribuida.
En el caso de memoria compartida, tenemos
como opciones:
> trabajar con procesos (UNIX)
> usar threads: Pthreads (POSIX), Java, OpenMP…
14. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 14
30/01/2023
Plataformas de memoria compartida
• En MPI: division de tareas y comunicación
es explícita.
• En memoria compartida es semi-implícita.
– Además la comunicación es a través de la
memoria común.
• Tecnologías: OpenMP, Parallel toolbox de
Matlab
15. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 15
30/01/2023
Procesos
• “Un proceso es un programa ejecutándose dentro
de su propio espacio de direcciones”.
• “Son instrucciones de un programa destinadas a
ser ejecutadas por el microprocesador”
• Se puede decir que un proceso es un supervisor
de hilo(s) de ejecución.
16. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 16
30/01/2023
heap
pila IR
proceso j
rutinas interrup.
código
ficheros
Procesos
procesos concurrentes: Fork / Join
gran overhead, son muy “caros”
17. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 17
30/01/2023
Threads
• Un hilo es una secuencia de código en
ejecución dentro del contexto de un
proceso.
• Los hilos no pueden ejecutarse ellos solos.
• Requieren la supervisión de un proceso
padre para correr.
• Dentro de cada proceso
hay un hilo o varios hilos
ejecutándose.
18. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 18
30/01/2023
heap
rutinas interrup.
código
ficheros
pila IR
thread 1
pila IR
thread 2
Threads concurrentes
los threads son más “ligeros”
la sincronización (variables compartidas) es sencilla
habitual en el S.O. (solaris, windows XP…)
19. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 19
30/01/2023
Para los sistemas de memoria distribuida, el
estándar actual de programación, mediante paso
de mensajes, es MPI.
Para los sistemas de memoria compartida, de tipo
SMP, la herramienta más extendida es OpenMP.
En ambos casos hay más opciones, y en una
máquina más general utilizaremos probablemente
una mezcla de ambos.
Programación de memoria compartida
vs distribuida
20. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 20
30/01/2023
Qué esperamos de una “herramienta” para
programar aplicaciones en máquinas de memoria
compartida:
• un mecanismo de identificación de los threads.
• un método para declarar las variables como privadas
(private) o compartidas (shared).
• un mecanismo para poder definir “regiones paralelas”,
bien sea a nivel de función o a nivel de iteración de
bucle.
• facilidades para sincronizar los threads.
Programación multiproceso de
memoria compartida
21. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 21
30/01/2023
Programación multiproceso de
memoria compartida
Qué no esperamos de una “herramienta” para
programar aplicaciones paralelas:
• un analizador de dependencias entre tareas (queda en
manos del programador).
22. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 22
30/01/2023
Unidad 4: Programación paralela y
distribuida
• Interfaz de programación de aplicaciones OpenMP y
de paso de mensajes MPI
• Programación multiproceso de memoria compartida
– Desarrollo de programas con OpenMP
– Modelo de programación paralela
• Programación concurrente y distribuida.
– High Performance Computing
– Interfaz de paso de Mensajes MPI
– Desarrollo de programas con MPI
• Desarrollo de programas distribuidos.
23. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 23
30/01/2023
100s of (mostly dead)
Parallel Programming Languages
ActorScript Concurrent Pascal JoCaml Orc
Ada Concurrent ML Join Oz
Afnix Concurrent Haskell Java Pict
Alef Curry Joule Reia
Alice CUDA Joyce SALSA
APL E LabVIEW Scala
Axum Eiffel Limbo SISAL
Chapel Erlang Linda SR
Cilk Fortan 90 MultiLisp Stackless Python
Clean Go Modula-3 SuperPascal
Clojure Io Occam VHDL
Concurrent C Janus occam-π XC
24. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 24
30/01/2023
OpenMP: Introducción
OpenMP es el estándar actual para programar
aplicaciones paralelas en sistemas de memoria
compartida.
No se trata de un nuevo lenguaje de programación,
sino de un API (application programming interface)
formado por:
directivas para el compilador
(C) #pragma omp <directiva>
unas pocas funciones de biblioteca
algunas variables de entorno
25. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 25
30/01/2023
OpenMP: Introducción
El modelo de programación
paralela que aplica OpenMP
es Fork - Join.
En un determinado
momento, el thread master
genera P threads que se
ejecutan en paralelo.
thread master
FORK
JOIN
región paralela
thread master
26. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 26
30/01/2023
OpenMP: Introducción
Todos los threads ejecutan la misma copia del
código (SPMD). A cada thread se le asigna un
identificador (tid).
Para diferenciar las tareas ejecutadas por cada
thread:
if (tid == 0) then ... else ...
constructores específicos de reparto de tareas
(work sharing).
27. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 27
30/01/2023
OpenMP: Introducción
En resumen, partiendo de un programa serie, para
obtener un programa paralelo OpenMP hay que
añadir:
directivas que especifican una región paralela
(código replicado), reparto de tareas
(específicas para cada thread), o sincronización
entre threads.
funciones de biblioteca (include <omp.h>):
para gestionar o sincronizar los threads..
28. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 28
30/01/2023
OpenMP: Ejemplo
main () {
for (i=0; i<1000; i++)
{ A[i] = A[i] + 1;
B = B + A[i];
}
printf(“ B = %d n”, B);
}
#pragma omp parallel private(tid)
{
}
tid = omp_get_thread_num();
printf (“ thread %d en marcha n”, tid);
#pragma omp for schedule(static) reduction(+:B)
if (tid==0)
29. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 29
30/01/2023
OpenMP: Conceptos básicos
0 Procesos paralelos (threads).
1 REGIONES PARALELAS. Ámbito de las variables.
2 REPARTO DE TAREAS.
Datos: bucles for. Reparto de iteraciones.
Funciones: sections / single / ...
3 SINCRONIZACIÓN.
Secciones críticas, cerrojos, barreras.
30. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 30
30/01/2023
OpenMP: Conceptos básicos
0 Número de threads
estático, una variable de entorno::
> export OMP_NUM_THREADS = 10
dinámico, mediante una función:
omp_set_num_threads (10);
0 ¿Quién soy / cuántos somos?
tid = omp_get_thread_num();
nth = omp_get_num_threads();
31. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 31
30/01/2023
OpenMP: Regiones paralelas
1 REGIÓN PARALELA (parallel regions)
# pragma omp parallel [VAR,...]
{ código }
Una región paralela es un trozo de código que se va
a repetir y ejecutar en paralelo en todos los threads.
Las variables de una región paralela pueden ser
compartidas (shared) o privadas (private).
1
32. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 32
30/01/2023
OpenMP: Regiones paralelas
> Un ejemplo sencillo:
...
#define N 12
int i, tid, nth, A[N];
main ( ) {
for (i=0; i<N; i++) A[i]=0;
#pragma omp parallel
{ nth = omp_get_num_threads ();
tid = omp_get_thread_num ();
printf ("Thread %d de %d en marcha n", tid, nth);
A[tid] = 10 + tid;
printf (" El thread %d ha terminado n", tid);
}
for (i=0; i<N; i++) printf (“A(%d) = %d n”, i, A[i]);
}
private(tid,nth) shared(A)
barrera
33. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 33
30/01/2023
OpenMP: Regiones paralelas
Ambiente de datos
• OpenMP usa un modelo de programación de
memoria compartida
– La mayoría de las variables por default son
compartidas.
– Las variables globales son compartidas entre threads
– Pero, no todo es compartido...
• Las variables en el stack en funciones llamadas en regiones
paralelas son PRIVADAS
• Las variables automáticas dentro de un bloque son
PRIVADAS
• Las variables de índices en ciclos son privadas (salvo
excepciones)
– C/C+: La primera variable índice en el ciclo en ciclos
anidados después de un #pragma omp for
34. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 34
30/01/2023
OpenMP: Regiones paralelas
Ambiente de datos
• Las variables declaradas fuera del bloque
paralelo son (por defecto) compartidas.
• La instrucción private(x) crea una nueva
versión privada de la variable x para cada
thread.
int i, temp, A[], B[];
#pragma omp parallel for private(temp)
for (i=0; i<N; i++)
{ temp = A[i]; A[i] = B[i]; B[i] = temp; }
Nota: No tiene que
declarar como privada la
variable i de índice de
bucle, ya que es así de
forma predeterminada
35. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 35
30/01/2023
OpenMP: Regiones paralelas
Atributos del alcance de datos
• El estatus por default puede modificarse
default (shared | none)
• Clausulas del atributo de alcance
shared(varname,…)
private(varname,…)
36. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 36
30/01/2023
OpenMP: Regiones paralelas
La cláusula private
• Reproduce la variable por cada hilo
– Las variables no son inicializadas; en C++ el objeto
es construido por default
– Cualquier valor externo a la región paralela es
indefinido
void* work(float* c, int N) {
float x, y; int i;
#pragma omp parallel for private(x,y)
for(i=0; i<N; i++) {
x = a[i]; y = b[i];
c[i] = x + y;
}
}
37. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 37
30/01/2023
OpenMP: Regiones paralelas
La cláusula shared: Ejemplo - producto punto
float dot_prod(float* a, float* b, int N)
{
float sum = 0.0;
#pragma omp parallel for shared(sum)
for(int i=0; i<N; i++) {
sum += a[i] * b[i];
}
return sum;
}
¿Qué es incorrecto?
38. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 38
30/01/2023
OpenMP: Regiones paralelas
La cláusula shared: Ejemplo - producto punto
• Debe proteger el acceso a los datos compartidos
que son modificables → sección crítica
float dot_prod(float* a, float* b, int N)
{
float sum = 0.0;
#pragma omp parallel for shared(sum)
for(int i=0; i<N; i++) {
#pragma omp critical
sum += a[i] * b[i];
}
return sum;
}
Lo veremos después…
39. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 39
30/01/2023
OpenMP: Reparto de tareas - bucles
2 REPARTO DE TAREAS: bucles
Los bucles son uno de los puntos de los que extraer
paralelismo de manera “sencilla” (paralelismo de
datos (domain decomposition) de grano fino).
Obviamente, la simple replicación de código no es
suficiente. Por ejemplo,
#pragma omp parallel shared(A) private(i)
{
for (i=0; i<100; i++)
A[i] = A[i] + 1;
}
?
2
40. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 40
30/01/2023
OpenMP: Reparto de tareas - bucles
Tendríamos que hacer algo así:
#pragma omp parallel shared(A)
private(tid,nth, ini,fin,i)
{ tid = omp_get_thread_num();
nth = omp_get_num_threads();
ini = tid * 100 / nth;
fin = (tid+1) * 100 / nth;
for (i=ini; i<fin; i++) A[i] = A[i] + 1;
}
!
El reparto de bucles se realiza automáticamente con la
directiva pragma omp for.
41. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 41
30/01/2023
OpenMP: Reparto de tareas - bucles
#pragma omp parallel [...]
{ …
#pragma omp for [clausulas]
for (i=0; i<100; i++) A[i] = A[i] + 1;
…
}
ámbito variables
reparto iteraciones
sincronización
0..24
25..49
50..74
75..99
barrera
42. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 42
30/01/2023
OpenMP: Reparto de tareas - bucles
• Los hilos se asignan a un
conjunto de iteraciones
independientes
• Los hilos deben de esperar
al final del bloque de
construcción de trabajo en
paralelo
#pragma omp parallel
#pragma omp for
Barrera implícita
i = 0
i = 1
i = 2
i = 3
i = 4
i = 5
i = 6
i = 7
i = 8
i = 9
i = 10
i = 11
#pragma omp parallel
#pragma omp for
for(i = 0; i < 12; i++)
c[i] = a[i] + b[i]
43. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 43
30/01/2023
OpenMP: Reparto de tareas – bucles
Combinando pragmas
Ambos segmentos de código son equivalentes
#pragma omp parallel
{
#pragma omp for
for (i=0; i< MAX; i++) {
res[i] = huge();
}
}
#pragma omp parallel for
for (i=0; i< MAX; i++) {
res[i] = huge();
}
44. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 44
30/01/2023
OpenMP: Reparto de tareas - bucles
for (i=0; i<N; i++)
for (j=0; j<M; j++)
{
X = B[i][j] * B[i][j];
A[i][j] = A[i][j] + X;
C[i][j] = X * 2 + 1;
}
Se ejecutará en paralelo el bucle externo, y los threads
ejecutarán el bucle interno. Paralelismo de grano “medio”.
Las variables i, j y X se declaran como privadas.
#pragma omp parallel for
private (i,j,X)
for (i=0; i<N; i++)
for (j=0; j<M; j++)
{
X = B[i][j] * B[i][j];
A[i][j] = A[i][j] + X;
C[i][j] = X * 2 + 1;
}
45. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 45
30/01/2023
OpenMP: Reparto de tareas - bucles
for (i=0; i<N; i++)
for (j=0; j<M; j++)
{
X = B[i][j] * B[i][j];
A[i][j] = A[i][j] + X;
C[i][j] = X * 2 + 1;
}
Los threads ejecutarán en paralelo el bucle interno (el
externo se ejecuta en serie). Paralelismo de grano fino.
Las variables j y X se declaran como privadas.
for (i=0; i<N; i++)
#pragma omp parallel for
private (j,X)
for (j=0; j<M; j++)
{
X = B[i][j] * B[i][j];
A[i][j] = A[i][j] + X;
C[i][j] = X * 2 + 1;
}
46. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 46
30/01/2023
OpenMP: Reparto de las iteraciones
Ocupado
Ocioso
#pragma omp parallel
{
#pragma omp for
for( ; ; ){
}
}
tiempo
Cargas de trabajo desiguales(no balanceadas)
producen hilos ociosos y desperdicio de tiempo.
47. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 47
30/01/2023
OpenMP: Reparto de las iteraciones
¿Cómo se reparten las iteraciones de un bucle entre
los threads?
Puesto que el pragma for termina con una barrera,
si la carga de los threads está mal equilibrada
tendremos una pérdida (notable) de eficiencia.
La cláusula schedule permite definir diferentes
estrategias de reparto, tanto estáticas como
dinámicas.
48. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 48
30/01/2023
OpenMP: Reparto de las iteraciones
• La cláusula schedule afecta en como las
iteraciones del ciclo se mapean a los hilos
schedule(static [,chunk])
• Bloques de iteraciones de tamaño “chunk” a los hilos
• Distribución Round Robin
schedule(dynamic[,chunk])
• Los hilos timan un fragmento (chunk) de iteraciones
• Cuando terminan las iteraciones, el hilo solicita el
siguiente fragmento
schedule(guided[,chunk])
• Planificación dinámica comenzando desde el bloque
más grande
• El tamaño de los bloques se compacta; pero nunca
más pequeño que “chunk”
49. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 49
30/01/2023
Cláusula Schedule Cuando utilizar
STATIC Predecible y trabajo
similar por iteración
DYNAMIC Impredecible, trabajo
altamente variable por
iteración
GUIDED Caso especial de
dinámico para reducir la
sobrecarga de
planificación
OpenMP: Reparto de las iteraciones
Qué planificación utilizar
50. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 50
30/01/2023
OpenMP: Reparto de las iteraciones
Qué planificación utilizar
51. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 51
30/01/2023
OpenMP: Reparto de las iteraciones
❖ Las iteraciones se dividen en pedazos de 8
▪ Si start = 3, el primer pedazo es i={3,5,7,9,11,13,15,17}
#pragma omp parallel for schedule (static, 8)
for( int i = start; i <= end; i += 2 )
{
if ( TestForPrime(i) ) gPrimesFound++;
}
Recuerda:
estático menos coste / mejor localidad datos
dinámico más coste / carga más equilibrada
52. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 52
30/01/2023
OpenMP: Rep.de tareas: funciones
#pragma omp parallel [clausulas]
{
#pragma omp sections [clausulas]
{
#pragma omp section
fun1();
#pragma omp section
fun2();
#pragma omp section
fun3();
}
}
2 REPARTO DE TAREAS: funciones
También puede usarse paralelismo de función (function
decomposition), mediante la directiva sections.
fun1
fun2
fun3
pragma omp sections
2
53. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 53
30/01/2023
OpenMP: Rep.de tareas: funciones
• Secciones independientes de código
se pueden ejecutar
concurrentemente
Serial Paralela
#pragma omp parallel sections
{
#pragma omp section
phase1();
#pragma omp section
phase2();
#pragma omp section
phase3();
}
2 REPARTO DE TAREAS: funciones
54. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 54
30/01/2023
OpenMP: Rep.de tareas: funciones
2 REPARTO DE TAREAS: funciones
Dentro de una región paralela, la directiva single
asigna una tarea a un único thread.
Sólo la ejecutará un thread, pero no sabemos cúal.
Barrera implícita al final
#pragma omp parallel
{
DoManyThings();
#pragma omp single
{
ExchangeBoundaries();
} // threads wait here for single
DoManyMoreThings();
}
55. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 55
30/01/2023
OpenMP: Rep.de tareas: funciones
2 REPARTO DE TAREAS: funciones
Dentro de una región paralela, la directiva master
asigna una tarea al thread maestro.
Sólo la ejecutará el thread maestro.
No hay barrera implícita al final
#pragma omp parallel
{
DoManyThings();
#pragma omp master
{ // if not master skip to next stmt
ExchangeBoundaries();
}
DoManyMoreThings();
}
56. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 56
30/01/2023
OpenMP: Sincronización de threads
3 SINCRONIZACIÓN
Cuando no pueden eliminarse las dependencias de
datos entre los threads, entonces es necesario
sincronizar su ejecución.
OpenMP proporciona los mecanismos de
sincronización más habituales: exclusión mutua y
sincronización por eventos.
3
57. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 57
30/01/2023
• #pragma omp critical [(lock_name)]
• Define una región crítica en un bloque estructurado
OpenMP: Sincronización de threads
float R1, R2;
#pragma omp parallel
{ float A, B;
#pragma omp for
for(int i=0; i<niters; i++){
B = big_job(i);
#pragma omp critical
consum (B, &R1);
A = bigger_job(i);
#pragma omp critical
consum (A, &R2);
}
}
Los hilos esperan su
turno –en un momento,
solo uno llama consum()
protegiendo R1 y R2 de
condiciones de carrera.
Nombrar las regiones
críticas es opcional, pero
puede mejorar el
rendimiento.
(R1_lock)
(R2_lock)
a. Secciones críticas: pragma omp critical
58. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 58
30/01/2023
OpenMP: Sincronización de threads
a. Secciones críticas: pragma omp critical
Por ejemplo, calcular el
máximo y el mínimo de
los elementos de un
vector.
#pragma omp parallel for
for (i=0; i<N; i++)
{
A[i] = fun(i);
if (A[i]>MAX)
#pragma omp critical(SMAX)
{ if (A[i]>MAX) MAX = A[i]; }
if (A[i]<MIN)
#pragma omp critical(SMIN)
{ if (A[i]<MIN) MIN = A[i]; }
}
59. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 59
30/01/2023
OpenMP: Sincronización de threads
a. Secciones críticas: pragma omp atomic
Una sección crítica para una operación simple de
tipo RMW. Por ejemplo,
#pragma omp parallel ...
{
...
#pragma omp atomic
X = X + 1;
...
}
60. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 60
30/01/2023
OpenMP: Sincronización de threads
b. Cerrojos
- omp_set_lock (&C)
espera a que el cerrojo C esté abierto; en ese
momento, cierra el cerrojo en modo atómico.
- omp_unset_lock (&C)
abre el cerrojo C.
- omp_test_lock (&C)
testea el valor del cerrojo C; devuelve T/F.
61. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 61
30/01/2023
OpenMP: Sincronización de threads
> Ejemplo
#pragma omp parallel private(nire_it)
{
omp_set_lock(&C1);
mi_it = i;
i = i + 1;
omp_unset_lock(&C1);
while (mi_it<N)
{
A[mi_it] = A[mi_it] + 1;
omp_set_lock(&C1);
mi_it = i;
i = i + 1;
omp_unset_lock(&C1);
}
}
62. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 62
30/01/2023
#pragma omp parallel
{
#pragma omp critical
{
...
}
...
}
OpenMP: Sincronización de threads
• Tiempo perdido por locks
tiempo
Ocupado
Ocioso
En SC*
*SC=sección crítica
63. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 63
30/01/2023
OpenMP: Sincronización de threads
#pragma omp parallel private(tid)
{
tid = omp_get_thread_num();
A[tid] = fun(tid);
#pragma omp for
for (i=0; i<N; i++) B[i] = fun(A,i);
#pragma omp for
for (i=0; i<N; i++) C[i] = fun(A,B,i);
D[tid] = fun(tid);
}
c. Barreras: pragma omp barrier
#pragma omp barrier
nowait
64. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 64
30/01/2023
OpenMP: Sincronización de threads
• Varios bloques de construcción de OpenMP*
tienen barreras implícitas
• parallel
• for
• single
• Barreras innecesarias deterioran el
rendimiento
• Esperar hilos implica que no se trabaja!
• Suprime barreras implícitas cuando sea
seguro con la cláusula nowait.
65. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 65
30/01/2023
OpenMP: Sincronización de threads
Cláusula Nowait
• Cuando los hilos esperarían entren
cómputos independientes
#pragma single nowait
{ [...] }
#pragma omp for nowait
for(...)
{...};
#pragma omp for schedule(dynamic,1) nowait
for(int i=0; i<n; i++)
a[i] = bigFunc1(i);
#pragma omp for schedule(dynamic,1)
for(int j=0; j<m; j++)
b[j] = bigFunc2(j);
66. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 66
30/01/2023
OpenMP: Cláusula de reducción
• Las variables en “list” deben ser compartidas
dentro de la región paralela
• Adentro de parallel o el bloque de
construcción de trabajo en paralelo:
– Se crea una copia PRIVADA de cada variable de
la lista y se inicializa de acuerdo al “op”
– Estas copias son actualizadas localmente por los
hilos
– Al final del bloque de construcción, las copias
locales se combinan de acuerdo al “op” a un solo
valor y se almacena en la variable COMPARTIDA
original
d. Reducción: reduction (op : list)
67. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 67
30/01/2023
OpenMP: Cláusula de reducción
Ejemplo de reducción
• Una copia local de sum para cada hilo
• Todas las copias locales de sum se suman
y se almacenan en una variable “global”
#pragma omp parallel for reduction(+:sum)
for(i=0; i<N; i++) {
sum += a[i] * b[i];
}
68. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 68
30/01/2023
• Un rango de operadores asociativos y
conmutativos pueden usarse con la reducción
• Los valores iniciales son aquellos que tienen
sentido
OpenMP: Cláusula de reducción
C/C++ Operaciones de reducción
Operador Valor Inicial
+ 0
* 1
- 0
^ 0
Operador Valor Inicial
& ~0
| 0
&& 1
|| 0
69. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 69
30/01/2023
Ejemplo de integración numérica
4.0
2.0
1.0
0.0
4.0
(1+x2)
f(x) =
4.0
(1+x2)
dx =
0
1
X
static long num_steps=100000;
double step, pi;
void main()
{ int i;
double x, sum = 0.0;
step = 1.0/(double) num_steps;
for (i=0; i< num_steps; i++){
x = (i+0.5)*step;
sum = sum + 4.0/(1.0 + x*x);
}
pi = step * sum;
printf(“Pi = %fn”,pi);
}
70. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 70
30/01/2023
Calculando Pi
• Paralelice el código de
integración numérica
usando OpenMP
• ¿Qué variables se
pueden compartir?
• ¿Qué variables deben
ser privadas?
• ¿Qué variables
deberían considerarse
para reducción?
static long num_steps=100000;
double step, pi;
void main()
{ int i;
double x, sum = 0.0;
step = 1.0/(double) num_steps;
for (i=0; i< num_steps; i++){
x = (i+0.5)*step;
sum = sum + 4.0/(1.0 + x*x);
}
pi = step * sum;
printf(“Pi = %fn”,pi);
}
71. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 71
30/01/2023
Calculando Pi
#include <omp.h>
#include <stdio.h>
static long num_steps=100000; double step;
void main()
{ int i;
double x, pi, sum = 0.0;
step = 1.0/(double) num_steps;
#pragma omp parallel for private(x) reduction(+:sum)
for (i=0; i< num_steps; i++){
x = (i+0.5)*step;
sum = sum + 4.0/(1.0 + x*x);
}
pi = step * sum;
printf(“Pi = %fn”,pi);
}
Nota: No tiene que declarar
como privada la variable i
de índice de bucle, ya que
ya que es así de forma
predeterminada
72. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 72
30/01/2023
OpenMP: Resumen
Variables de entorno y funciones (núm. de hilos,
identificadores...)
Directiva para definir regiones paralelas
#pragma omp parallel [var…]
Directivas de reparto de tareas
#pragma omp for [var,sched…]
#pragma omp sections [var]
Directivas y funciones de sincronización
#pragma omp critical [c] / atomic
#pragma omp barrier
cerrojos (set_lock, unset_lock, test_lock)
reducción (reduction (op : list))
73. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 73
30/01/2023
Unidad 4: Programación paralela y
distribuida
• Interfaz de programación de aplicaciones OpenMP y
de paso de mensajes MPI
• Programación multiproceso de memoria compartida
– Desarrollo de programas con OpenMP
– Modelos de programación paralela
• Programación concurrente y distribuida.
– High Performance Computing
– Interfaz de paso de Mensajes MPI
– Desarrollo de programas con MPI
• Desarrollo de programas distribuidos.
74. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 74
30/01/2023
¿Qué es la programación paralela?
• Uso de varios procesadores trabajando juntos para resolver
una tarea común:
– Cada procesador trabaja en una porción del problema.
– Los procesos pueden intercambiar datos, a través de la
memoria o por una red de interconexión.
• Muchas posibilidades:
– Pipeline
– Cachés
– Paralelismo a nivel de instrucción
– Ejecución fuera de orden
– Especulación
– Varios procesadores en un chip
– LAN de altas prestaciones
75. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 75
30/01/2023
¿Qué es la programación paralela?
• Programación concurrente:
Varios procesos trabajando en la solución de un problema, puede ser
paralela (varios procesadores)
• Computación heterogénea:
Varios procesadores con características distintas
• Programación adaptativa:
Durante la ejecución el programa se adapta a las características del
sistema
• Programación distribuida:
Varios procesadores geográficamente distribuidos. Hay paso de
mensajes pero se necesita infraestructura especial
• Computación en la web:
Necesidad de herramientas que permitan la utilización de sistemas de
computación en la web
• Computación cuántica o biológica
76. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 76
30/01/2023
Concurrencia vs Paralelismo
• Concurrencia: Capacidad de operar actividades al mismo
tiempo. Es decir se pueden tener varios procesos corriendo
cada uno en un procesador o puede haber varios proceso
que corran solo en un procesador
• Paralelismo: Son muchas actividades teniendo lugar al
mismo tiempo, “la cualidad o el estado de ser paralelo”. El
hecho de ser paralelo implica que solo se pueden tener varios
procesos corriendo cada uno en un procesador.
77. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 77
30/01/2023
Tipos de paralelismo
1) Paralelismo a nivel de bit:
• Se habla de paralelismo al nivel de bit, cuando se aumenta el
tamaño de la palabra del procesador (tamaño de la cadena
de bits a procesar).
• Este aumento reduce el número de instrucciones que tiene
que ejecutar el procesador en variables cuyos tamaños sean
mayores a la longitud de la cadena.
• Ejemplo: En un procesador de 8-bits sumar dos números de
16bits tomaría dos instrucciones. En un procesador de 16-bits
esa operación requiere solo una instrucción.
Nota: este método está “estancado” desde el establecimiento de las arquitecturas de 32 y 64 bits.
78. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 78
30/01/2023
Tipos de paralelismo
2) Paralelismo a nivel de instrucción
• Este tipo de paralelismo consiste en cambiar el orden
de las intrucciones de un programa y juntarlas en
grupos para posteriormente ser ejecutados en
paralelo sin alterar el resultado final del programa.
• Ejemplo: Un pipeline de 5 etapas: fetch (buscar la
instrucción), decode (decodificarla), execute (ejecutarla),
write (escribir en memoria el resultado de la operación).
En el gráfico anterior se
observa el procesamiento
de dos instrucciones sin
pipeline, tomando un
tiempo de 8 ciclos, y con
pipeline reduciendo este
tiempo a solo 5 ciclos.
79. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 79
30/01/2023
Tipos de paralelismo
3) Paralelismo a nivel de datos
• Cada procesador realiza la misma tarea sobre un
subconjunto independiente de datos.
• Ej: Dos granjeros se dividen el área de césped a podar.
• El caso clásico de paralelismo de datos, es el cálculo de
pi por partes usando el método de monte carlo:
80. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 80
30/01/2023
Tipos de paralelismo
4) Paralelismo a nivel de tareas
• Cada hilo realiza una tarea distinta e independiente de
las demás.
• Ej: Un granjero poda el césped, el otro cosecha.
81. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 81
30/01/2023
Modelos de programación paralela
• En la actualidad existen diversos modelos de
programación paralela, ellos se agrupan de
acuerdo a:
– el método de comunicación entre los diferentes
elementos de cómputo,
– los mecanismos de acceso a la memoria de
datos del programa,
– la forma de gestionar las ejecución de las tareas
y,
– más recientemente… de acuerdo con la
heterogeneidad del hardware sobre el cual
pueden ser implementados.
82. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 82
30/01/2023
Modelos de programación paralela
1) Modelo de intercambio de mensajes:
• El algoritmo es dividido en piezas que serán procesadas
dentro de un cluster (región) de nodos (CPUs) que están
conectados por un bus de intercomunicación.
• La sincronización de los procesos ocurre por intercambio de
mensajes entre los nodos. En cada CPU la memoria es
compartida y cada núcleo se hace cargo de un proceso.
Usualmente es utilizado para ejecutar muchas veces el
mismo proceso con la misma distribución de procesamiento
por cluster.
• El usuario escribirá su aplicación como un proceso secuencial
del que se lanzarán varias instancias que cooperan entre sí.
A pesar que se comparte localmente la memoria, es
considerado un modelo de memoria distribuida debido a que
cada nodo dispone de su propia memoria local.
• La aplicación más representativa de este modelo es MPI.
84. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 84
30/01/2023
Modelos de programación paralela
2) Modelo de programación por hilos:
• Este modelo busca la ejecución de múltiples tareas
simultáneamente. Es un modelo de memoria
compartida.
• Su estructura base es un hilo el cual es una unidad de
ejecución que contiene instrucciones de un programa y
la estructura de memoria necesaria para su ejecución
independiente.
• La aplicación precursora de este modelo es POSIX
Threads.
86. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 86
30/01/2023
Modelos de programación paralela
3) Modelos heterogéneos:
• Durante las últimas dos décadas los servidores, computadoras
personales y PMD que utilizan tanto CPU como GPU se han vuelto
más comunes en la industria del hardware.
• La aparición de estos equipos con tecnologías heterogéneas de
procesamiento ha promovido un nuevo modelo de programación
paralela: modelo de programación heterogéneo.
• En este entorno, el modelo de programación intenta aprovechar al
máximo los recursos de cálculo del sistema disponibles mediante el
uso de API y herramientas funcionales sin la necesidad de abordar
paradigmas específicos de hardware (para CPU ó para GPU) o las
limitantes de desempeño computacional entre ellos.
• En este tipo de modelos, los cálculos son gestionados por un
procesador host que provee control sobre otros equipos
computacionales (CPU/GPU). La programación paralela es
realizada usando programas kernel los cuales implementan la
funcionalidad que será ejecutada por los devices (equipos
computacionales).
• El framework más representativo de este modelo es OpenCL.
88. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 88
30/01/2023
Modelos de programación paralela
¿Cuál modelo seleccionar?
• Seleccionar el mejor modelo de programación paralela
dependerá del tipo de tarea a ejecutar, el dominio del negocio
y la aplicación que necesitamos implementar.
– Por ejemplo, si se intenta realizar una implementación en donde
los datos requeridos para el algoritmo son muy grandes, en
primera instancia se podría pensar en un modelo de memoria
distribuida, en donde de ser necesario se distribuye el
procesamiento de los datos en varios nodos y se usa el modelo
MPI para la implementación.
– Sin embargo, si por ejemplo se tiene un algoritmo secuencial
que ya está funcionando y lo que queremos es hacerlo más
eficiente aprovechando un nuevo hardware y también sabemos
que el requerimiento de memoria no es muy alto , se podría
pensar en el uso de OpenMP pues además incluye directivas
que ayudan en la paralelización del algoritmo.
– También se puede pensar en darle solución a la necesidad
mediante un sistema híbrido por ejemplo: MPI + OpenMP.
89. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 89
30/01/2023
Modelos de programación paralela
¿Cuál modelo seleccionar?
• Sin embargo, siempre se debe tener en cuenta que el modelo
seleccionado debería cumplir las siguientes propiedades:
– Desempeño: El desempeño del modelo debe ser predecible, aún si se
escala a sistemas más grandes.
– Productividad: El modelo debería disponer de herramientas que le
permitan monitorear y ajustar su desempeño y debe contener las
librerías y herramientas suficientes para realizar las implementaciones
de forma fácil y eficiente.
– Portabilidad: El modelo debe ser escalable a otros sistemas de
hardware actuales y futuros.
90. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 90
30/01/2023
Necesidad de la programación paralela
• Límites para una única CPU
– Memoria disponible
– Prestaciones
• La programación paralela permite:
– Resolver problemas que no caben en una CPU
– Resolver problemas que no se resuelven en un tiempo
razonable
• Se pueden ejecutar
– Problemas mayores
– Más rápidamente
– Más problemas
91. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 91
30/01/2023
Necesidad de la programación paralela
• La velocidad de los computadores secuenciales
convencionales se ha incrementado continuamente
para adaptarse a las necesidades de las aplicaciones
- Procesadores de E/S. Procesamiento en tiempo
compartido.
- Jerarquía de Memorias. Memorias cache.
- División de la memoria principal en bloques.
- Multiplicidad de unidades funcionales
- Segmentación encauzada dentro de la CPU. Pipeline.
92. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 92
30/01/2023
Necesidad de la programación paralela
• El rendimiento de los computadores secuenciales está comenzando a
saturarse.
• Solución: Usar varios procesadores. Sistemas paralelos. Con la
tecnología VLSI, el costo de los procesadores es menor.
• Aspectos a tener en cuenta en la computación paralela son:
- Diseño de computadores paralelos. Escalabilidad y Comunicaciones.
- Diseño de algoritmos eficientes. No hay ganancia si los algoritmos
no se diseñan adecuadamente. ¿Mayor aceleración con mejores
algoritmos que con mejores sistemas?
- Métodos para evaluar los algoritmos paralelos: ¿Cómo de rápido se
puede resolver un problema usando una máquina paralela? ¿Con qué
eficiencia se usan esos procesadores?
- Lenguajes para computadores paralelos. Flexibles para permitir una
implementación eficiente y que sean fáciles de programar.
- Herramientas para la programación paralela.
- Programas paralelos portables.
- Compiladores paralelizantes.
93. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 93
30/01/2023
Unidad 4: Programación paralela y
distribuida
• Interfaz de programación de aplicaciones OpenMP y
de paso de mensajes MPI
• Programación multiproceso de memoria compartida
– Desarrollo de programas con OpenMP
– Modelo de programación paralela
• Programación concurrente y distribuida.
– High Performance Computing
– Interfaz de paso de Mensajes MPI
– Desarrollo de programas con MPI
• Desarrollo de programas distribuidos.
94. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 94
30/01/2023
¿Qué es la concurrencia?
• El paradigma de la programación
concurrente
• Paradigma
– Conjunto de teorías, estándares y métodos
que juntos representan una forma de ver el
mundo
• Concurrencia
– Acaecimiento de varios sucesos al mismo
tiempo
95. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 95
30/01/2023
¿Qué es la concurrencia?
Paralelismo Solapamiento
Simultaneidad
Tiempo
Tiempo
Tiempo
• Los sucesos se
producen en un mismo
intervalo de tiempo
(diferentes recursos)
• Los sucesos se
producen en el mismo
instante de tiempo
• Los sucesos se
producen en intervalos
de tiempo superpuestos
96. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 96
30/01/2023
Asignación de Procesos a
Procesadores
• Procesamiento Distribuido
– Cada proceso se ejecuta en su propio
procesador dentro de cada máquina de una red
(Programa distribuido)
Máquina 1
Router
Máquina 3
Proc1 Proc2 Proc3
Máquina 2
Impresora
Red
97. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 97
30/01/2023
Unidad 4: Programación paralela y
distribuida
• Interfaz de programación de aplicaciones OpenMP y
de paso de mensajes MPI
• Programación multiproceso de memoria compartida
– Desarrollo de programas con OpenMP
– Modelo de programación paralela
• Programación concurrente y distribuida.
– High Performance Computing
– Interfaz de paso de Mensajes MPI
– Desarrollo de programas con MPI
• Desarrollo de programas distribuidos.
98. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 98
30/01/2023
Ecuación no lineal de Schrödinger
Ecuaciones de Maxwell-Bloch Esquemas numéricos
∂u
=
ui +
1 −ui −
1
∂x h
k
h
Aplicaciones HPC (High Performance Computing)
• Su objetivo es reducir el tiempo de ejecución de una única aplicación paralela
• Su rendimiento se mide en número de operaciones en punto flotante por
segundo (FLOPS)
• Áreas de aplicación:
• Estudio de fenómenos a escala microscópica (dinámica de partículas)
• Resolución limitada por la potencia de cálculo del computador
• Cuantos más grados de libertad (puntos), mejor reflejo de la realidad
• Estudio de fenómenos a escala macroscópica (sistemas descritos por
ecuaciones diferenciales fundamentales)
• Precisión limitada por la potencia de cálculo del computador
• Cuantos más puntos, más se acerca la solución discreta a la continua
99. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 99
30/01/2023
Unidad 4: Programación paralela y
distribuida
• Interfaz de programación de aplicaciones OpenMP y
de paso de mensajes MPI
• Programación multiproceso de memoria compartida
– Desarrollo de programas con OpenMP
– Modelo de programación paralela
• Programación concurrente y distribuida.
– High Performance Computing
– Interfaz de paso de Mensajes MPI
– Desarrollo de programas con MPI
• Desarrollo de programas distribuidos.
100. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 100
30/01/2023
Interfaz de paso de Mensajes MPI
• La interfaz de paso de mensajes o MPI es un estándar
que define la sintaxis y la semántica de las funciones
contenidas en una biblioteca de paso de mensajes
diseñada para ser usada en programas que exploten
la existencia de múltiples procesadores, escritas
generalmente en C, C++, Fortran y Ada.
• La ventaja de MPI sobre otras bibliotecas de paso de
mensajes, es que los programas que utilizan la
biblioteca son:
– Portables: dado que MPI ha sido implementado para casi
toda arquitectura de memoria distribuida), y
– Rápidos: porque cada implementación de la biblioteca ha
sido optimizada para el hardware en la cual se ejecuta).
101. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 101
30/01/2023
Interfaz de paso de Mensajes MPI
Qué esperamos de una “herramienta” para
programar aplicaciones en máquinas de memoria
distribuida (MPI):
• un mecanismo de identificación de los procesos.
• una librería de funciones de comunicación punto a
punto: send, receive…
• funciones de comunicación global: broadcast,,
scatter, reduce...
• alguna función para sincronizar procesos.
102. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 102
30/01/2023
Interfaz de paso de Mensajes MPI
Qué no esperamos de una “herramienta” para
programar aplicaciones paralelas:
• un analizador de dependencias entre tareas (queda en
manos del programador).
103. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 103
30/01/2023
Unidad 4: Programación paralela y
distribuida
• Interfaz de programación de aplicaciones OpenMP y
de paso de mensajes MPI
• Programación multiproceso de memoria compartida
– Desarrollo de programas con OpenMP
– Modelo de programación paralela
• Programación concurrente y distribuida.
– High Performance Computing
– Interfaz de paso de Mensajes MPI
– Desarrollo de programas con MPI
• Desarrollo de programas distribuidos.
104. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 104
30/01/2023
Introducción
Si para los sistemas SMP la opción es OpenMP, el
“estándar” actual de programación de los sistemas
de memoria distribuida, mediante paso de
mensajes, es MPI (message-passing interface).
MPI es, básicamente, una librería (grande) de
funciones de comunicación para el envío y
recepción de mensajes entre procesos.
MPI indica explicitamente la comunicación entre
procesos, es decir:
-- los movimientos de datos
-- la sincronización
105. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 105
30/01/2023
Tipos de comunicación
Dos tipos de comunicación:
• punto a punto • global
El modelo de paralelismo que implementa MPI es
SPMD.
if (pid == 1) ENVIAR_a_pid2
else if (pid == 2) RECIBIR_de_pid1
Recuerda: cada proceso dispone de su propio
espacio independiente de direcciones.
106. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 106
30/01/2023
Tipos de comunicación
Modos de comunicación (1)
• síncrona
La comunicación no se produce hasta que emisor y
receptor se ponen de acuerdo.
• mediante un búfer
El emisor deja el mensaje en un búfer y retorna.
La comunicación se produce cuando el receptor está
dispuesto a ello. El búfer no se puede reutilizar hasta
que se vacíe.
107. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 107
30/01/2023
Tipos de comunicación
Modos de comunicación (2)
• bloqueante
Se espera a que la comunicación se produzca.
La comunicación síncrona es siempre bloqueante. En el
caso buffered, existen ambas alternativas.
• no bloqueante
Se retorna y se continúa con la ejecución.
Más adelante, se comprueba si la comunicación ya se
ha efectuado.
108. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 108
30/01/2023
Tipos de comunicación
Cada estrategia tiene sus ventajas e inconvenientes:
> síncrona: es más rápida si el receptor está dispuesto
a recibir; nos ahorramos la copia en el buffer.
Además del intercambio de datos, sirve para
sincronizar los procesos.
Ojo: al ser bloqueante es posible un deadlock!
> buffered: el emisor no se bloquea si el receptor no
está disponible, pero hay que hacer copia(s) del
mensaje (más lento).
109. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 109
30/01/2023
Introducción
MPI gestiona los procesos estáticamente (número y
asignación) (MPI2 también dinámicamente).
Cada proceso tiene un identificador o pid.
MPI agrupa los procesos implicados en una
ejecución paralela en “comunicadores”.
Un comunicador agrupa a procesos que pueden
intercambiarse mensajes.
El comunicador MPI_COMM_WORLD está creado por
defecto y engloba a todos los procesos.
110. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 110
30/01/2023
Funciones básicas
Aunque MPI consta de más de 300 funciones, el
núcleo básico lo forman sólo 6:
2 de inicio y finalización del programa.
2 de control del número de procesos.
2 de comunicación.
Sintaxis: MPI_Funcion(…)
111. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 111
30/01/2023
F. básicas: Init / Finalize
1. Comienzo y final del programa:
> MPI_Init(&argc, &argv);
> MPI_Finalize();
Estas dos funciones son la primera y última función
MPI que deben ejecutarse en un programa.
112. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 112
30/01/2023
F. básicas: Comm_rank / _size
2. Identificación de procesos
> MPI_Comm_rank(comm, &pid);
Devuelve en pid el identificador del proceso dentro
del comunicador comm especificado.
Los procesos se identifican mediante dos parámetros:
el pid y el grupo (comm, p.e., MPI_COMM_WORLD).
> MPI_Comm_size(comm, &npr);
Devuelve en npr el número de procesos del
comunicador comm.
113. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 113
30/01/2023
Funciones básicas
Un ejemplo sencillo
#include <stdio.h>
#include <mpi.h>
main (int argc, char *argv[])
{
int pid, npr, A = 2;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &pid);
MPI_Comm_size(MPI_COMM_WORLD, &npr);
A = A + 1;
printf(“Proc. %d de %d activado, A = %dn”, pid,npr,A);
MPI_Finalize();
}
114. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 114
30/01/2023
F. básicas: Send / Receive
3. Envío y recepción de mensajes
La comunicación entre procesos necesita (al menos) de
dos participantes: el emisor y el receptor.
El emisor ejecuta la función de envío de mensajes, y el
receptor la de recepción.
A B
enviar recibir
La comunicación es un proceso cooperativo. Si una de
las dos funciones no se ejecuta, la comunicación no tiene
lugar (y podría producirse un deadlock!).
115. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 115
30/01/2023
F. básicas: Send / Receive
> MPI_Send(&mess, count, type, dest,
tag, comm);
- mensaje: [mess (@com), count (tamaño), type]
- receptor: [dest, comm (grupo)]
- tag: dato de control, de 0 a 32767
(tipo de mensaje, orden...)
Función básica para enviar un mensaje:
116. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 116
30/01/2023
F. básicas: Send / Receive
> MPI_Recv(&mess, count, type, source,
tag, comm, &status);
- mensaje (espacio): [mess, count, type]
- emisor: [source, comm]
- tag: clase de mensaje...
- status: información de control sobre el mensaje recibido
Función básica para recibir un mensaje:
Recv se bloquea hasta que se recibe el mensaje.
117. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 117
30/01/2023
Ejemplo
...
#define N 10
int main (int argc, char **argv)
{
int pid, npr, orig, dest, ndat, tag;
int i, VA[N];
MPI_Status info;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD,&pid);
for (i=0;i<N;i++) VA[i] = 0;
if (pid == 0)
{
for (i=0;i<N;i++) VA[i] = i;
dest = 1; tag = 0;
MPI_Send(VA, N, MPI_INT, dest, tag,
MPI_COMM_WORLD);
}
else if (pid == 1)
{
for (i=0;i<N;i++) printf(“%4d”,VA[i]);
orig = 0; tag = 0;
MPI_Recv(VA, N, MPI_INT, orig, tag,
MPI_COMM_WORLD, &info);
MPI_Get_count(&info, MPI_INT, &ndat);
printf(“Datos de pr%d; tag = %d,
ndat = %d n”, info.MPI_SOURCE,
info.MPI_TAG, ndat);
for (i=0;i<ndat;i++)
printf(“%4d”,VA[i]);
}
MPI_Finalize();
}
118. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 118
30/01/2023
Más tipos de Send / Receive
Síncrono:
MPI_Ssend (&mes,count,datatype,dest,tag,comm);
Ssend no devuelve control hasta que el receptor comienza la
lectura.
Inmediato:
MPI_Isend (...);
Retorna nada más ejecutarse; luego, para saber si se ha
producido o no la comunicación:
MPI_Test (...) devuelve 0 o 1
MPI_Wait (...) espera a que finalice
119. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 119
30/01/2023
Comunicaciones colectivas
Muchas aplicaciones requieren de operaciones de
comunicación en las que participan muchos
procesos.
La comunicación es colectiva si participan en ella
todos los procesos del comunicador.
Ejemplo: un broadcast, envío de datos desde un
proceso a todos los demás.
¿Uno a uno en un bucle?
120. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 120
30/01/2023
Comunicaciones colectivas
Las funciones de comunicación colectiva son
bloqueantes.
Todos los procesos que forman parte del comunicador
deben ejecutar la función.
Tres tipos
1 Movimiento de datos
2 Operaciones en grupo
3 Sincronización
121. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 121
30/01/2023
CC: movimento de datos
1a Broadcast: envío de datos desde un proceso
(root) a todos los demás.
A
P0
P2 P3
P1
A A
A
(implementación logarítmica en árbol)
A
P0
P2 P3
P1
> MPI_Bcast(&mess, count, type, root, comm);
122. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 122
30/01/2023
CC: movimento de datos
ABCD
P0
P2 P3
P1
A B C D
P0
P2 P3
P1
1b Scatter: reparto de datos desde un proceso al resto
C
B
D
A
A
P0
P2 P3
P1
C D
B A
P0
P2 P3
P1
C D
B
ABCD
1c Gather: recolección de datos de todos los procesos
123. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 123
30/01/2023
KK: operaciones en grupo
2. Reduce (en árbol)
Allreduce: todos obtienen el resultado (Reduce + BC)
A
P0
P2 P3
P1
C D
B A
P0
P2 P3
P1
C D
B
A+B+C+D
124. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 124
30/01/2023
CC: sincronización
3. Barreras de sincronización
Sincronización global entre todos los procesos del
comunicador.
MPI_Barrier (comm);
La función se bloquea hasta que todos los procesos
del comunicador la ejecutan.
125. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 125
30/01/2023
Comunicaciones colectivas
> Ejemplo: V(i) = V(i) * V(j)
sum = 0;
for (j=0; j<N; i++) sum = sum + V[j];
for (i=0; i<N; i++) V[i] = V[i] * sum;
1. Leer N (el pid = 0)
2. Broadcast de N/npr (tamaño del vector local)
3. Scatter del vector V (trozo correspondiente)
4. Cálculo local de la suma parcial
5. Allreduce de sumas parciales (todos obtienen suma total)
6. Cálculo local de V(i) * sum
7. Gather de resultados
8. Imprimir resultados (el pid = 0)
126. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 126
30/01/2023
Ej.: cálculo del número pi
#include <stdio.h>
#include <mat.h>
#include “mpi.h”
int main (int argc, char **argv)
{
int pid, npr, i, n;
double PI = 3.1415926536;
double h, ×, pi_loc, pi_glob, sum;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD,&pid);
MPI_Comm_size(MPI_COMM_WORLD,&npr);
if (pid == 0)
{ printf(“ Núm de intervalos”;
scanf("%d",&n);
}
MPI_Bcast(&n, 1, MPI_INT, 0,
MPI_COMM_WORLD);
h = 1.0 / (double) n;
sum = 0.0;
for (i=pid; i<n; i+=npr)
{
x = (i + 0.5) * h;
sum += 4.0 / (1.0 + x*x);
}
pi_loc = h * sum;
MPI_Reduce(&pi_loc, &pi_glob, 1,
MPI_DOUBLE, MPI_SUM, 0,
MPI_COMM_WORLD);
if (pid == 0)
printf("pi(+/-) = %.16f, error
= %.16fn", pi_glob,
fabs(pi_glob - PI));
MPI_Finalize();
}
127. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 127
30/01/2023
Implementaciones de MPI
De libre distribución: MPICH / LAM
En general, previo a la ejecución en paralelo en un
máquina tipo cluster, se necesita:
- un fichero con la lista de máquinas que conforman
el sistema (identificadores en la red).
- unos daemons que se ejecuten en cada máquina.
- indicar, al ejecutar, el número concreto de procesos
que se desea generar:
mpiexec -n 8 pi
128. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 128
30/01/2023
Unidad 4: Programación paralela y
distribuida
• Interfaz de programación de aplicaciones OpenMP y
de paso de mensajes MPI
• Programación multiproceso de memoria compartida
– Desarrollo de programas con OpenMP
– Modelo de programación paralela
• Programación concurrente y distribuida.
– High Performance Computing
– Interfaz de paso de Mensajes MPI
– Desarrollo de programas con MPI
• Desarrollo de programas distribuidos.
130. Aplicaciones Distribuidas Carrera de Software
Ph.D. Franklin Parrales 130
30/01/2023
Programación paralela y
distribuida
Unidad 4
Final de la unidad
Y del curso…. !Muchas gracias
a todos!