paradigma “shared address space” algoritmos paralelos glen rodríguez
TRANSCRIPT
![Page 1: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/1.jpg)
Paradigma “Shared Address Space”
Algoritmos paralelos
Glen Rodríguez
![Page 2: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/2.jpg)
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
![Page 3: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/3.jpg)
Hilos
Un hilo es un flujo de control individual en un programa.
Ej. Mult.matrices. for (row = 0; row < n; row++) for (column = 0; column < n; column++) c[row][column] = create_thread(dot_product(get_row(a, row),
get_col(b, col)));
![Page 4: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/4.jpg)
Hilos o procesos accedena memoria compartida
Cada hilo puede tener variablesprivadas (stack)
![Page 5: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/5.jpg)
Por qué hilos?
Portabilidad de software Memoria tiene menos latencia (ts=α) que
las redes. Además solo 1 hilo puede usar la red en un momento dado.
Scheduling y balance de carga semi-automático.
Facilidad de programar.
![Page 6: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/6.jpg)
API de hilos de Posix
POSIX API : estándar IEEE 1003.1c-1995. Llamado Pthreads.
#include <pthread.h> int pthread_create ( pthread_t *thread_handle, const pthread_attr_t *attribute, void * (*thread_function)(void *), void *arg);
![Page 7: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/7.jpg)
Ejemplo1 #include <pthread.h> 2 #include <stdlib.h> 3 4 #define MAX_THREADS 512 5 void *compute_pi (void *); 6 7 int total_hits, total_misses, hits[MAX_THREADS], 8 sample_points, sample_points_per_thread, num_threads; 9 10 main() { 11 int i; 12 pthread_t p_threads[MAX_THREADS]; 13 pthread_attr_t attr; 14 double computed_pi; 15 double time_start, time_end; 16 struct timeval tv; 17 struct timezone tz; 18 19 pthread_attr_init (&attr); 20 pthread_attr_setscope (&attr,PTHREAD_SCOPE_SYSTEM); 21 printf("Enter number of sample points: "); 22 scanf("%d", &sample_points); 23 printf("Enter number of threads: "); 24 scanf("%d", &num_threads);
![Page 8: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/8.jpg)
Ejemplo26 gettimeofday(&tv, &tz); 27 time_start = (double)tv.tv_sec + 28 (double)tv.tv_usec / 1000000.0; 29 30 total_hits = 0; 31 sample_points_per_thread = sample_points / num_threads; 32 for (i=0; i< num_threads; i++) { 33 hits[i] = i; 34 pthread_create(&p_threads[i], &attr, compute_pi, 35 (void *) &hits[i]); 36 } 37 for (i=0; i< num_threads; i++) { 38 pthread_join(p_threads[i], NULL); 39 total_hits += hits[i]; 40 } 41 computed_pi = 4.0*(double) total_hits / 42 ((double)(sample_points)); 43 gettimeofday(&tv, &tz); 44 time_end = (double)tv.tv_sec + 45 (double)tv.tv_usec / 1000000.0; 46 47 printf("Computed PI = %lf\n", computed_pi); 48 printf(" %lf\n", time_end - time_start); 49 }
![Page 9: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/9.jpg)
Ejemplo51 void *compute_pi (void *s) { 52 int seed, i, *hit_pointer; 53 double rand_no_x, rand_no_y; 54 int local_hits; 55 56 hit_pointer = (int *) s; 57 seed = *hit_pointer; 58 local_hits = 0; 59 for (i = 0; i < sample_points_per_thread; i++) { 60 rand_no_x =(double)(rand_r(&seed))/(double)((2<<14)-1); 61 rand_no_y =(double)(rand_r(&seed))/(double)((2<<14)-1); 62 if (((rand_no_x - 0.5) * (rand_no_x - 0.5) + 63 (rand_no_y - 0.5) * (rand_no_y - 0.5)) < 0.25) 64 local_hits ++; 65 seed *= i; 66 } 67 *hit_pointer = local_hits; 68 pthread_exit(0); 69 }
![Page 10: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/10.jpg)
Primitivas de sincronización en Pthreads
Exclusión mutua para variables compartidas
Ej.: best_cost es compartida (=100 al inicio), my_cost es local (50 y 75)
1 /* each thread tries to update variable best_cost as follows */
2 if (my_cost < best_cost) 3 best_cost = my_cost;
![Page 11: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/11.jpg)
Mutex-locks
El if y la asignación no son independientes: deberían ser una unidad. Además son una zona crítica (pedazo del programa donde solo 1 hilo debe correr a la vez).
Como soportar zona crítica y ops. atómicas: mutex-locks (locks de exclusión mutua)
![Page 12: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/12.jpg)
Controlando atributos de Hilos y de Sincronización
Atributos de hilo: Tipo de scheduling Tamaño de stack
Atributos de mutez: tipo de mutex. Separo atributos del programa: más
fácil programar.
![Page 13: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/13.jpg)
Cancelando hilos
Si un hilo ya no es necesario: int pthread_cancel (pthread_t thread); Un hilo se puede autocancelar, o
puede cancelar a otros.
![Page 14: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/14.jpg)
Constructos compuestos de sincronización
Locks read-write Muchos hilos pueden leer una data a la
vez, pero sólo 1 puede escribir en ella. Y debería hacerlo sin reads a la vez.
Una vez que hay en cola un pedido de lock de escritura, ya no se aceptan más lecturas.
Barreras: similar a MPI
![Page 15: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/15.jpg)
Diseñando programas asíncronos
Alt. 1: no importa el orden de los hilos Alt. 2: sí importa, en este caso hay que programar
explícitamente el orden con locks, mutexes, barreras, joins etc,
Setear los atributos, datos, mutexes, etc. al inicio de la vida del hilo.
Si hay hilo productor y consumidor, asegurarse que se produzca (y se ponga en memoria compartida) antes de que se consuma.
Si se puede, definir y usar sincronizaciones de grupo y replicación de data.
![Page 16: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/16.jpg)
OpenMP ¿Qué es OpenMP? Regiones Paralelas Bloques de construcción para trabajo en
paralelo Alcance de los datos para proteger datos Sincronización Explícita Cláusulas de Planificación Otros bloques de construcción y cláusulas
útiles
![Page 17: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/17.jpg)
¿Qué es OpenMP*?
Directivas del compilador para programación multihilos
Es fácil crear hilos en Fortran y C/C++ Soporta el modelo de paralelismo de datos Paralelismo incremental
Combina código serial y paralelo en un solo código fuente
![Page 18: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/18.jpg)
¿Qué es OpenMP*?
omp_set_lock(lck)
#pragma omp parallel for private(A, B)
#pragma omp critical
C$OMP parallel do shared(a, b, c)
C$OMP PARALLEL REDUCTION (+: A, B)
call OMP_INIT_LOCK (ilok)
call omp_test_lock(jlok)
setenv OMP_SCHEDULE “dynamic”
CALL OMP_SET_NUM_THREADS(10)
C$OMP DO lastprivate(XX)
C$OMP ORDERED
C$OMP SINGLE PRIVATE(X)
C$OMP SECTIONS
C$OMP MASTER
C$OMP ATOMIC
C$OMP FLUSH
C$OMP PARALLEL DO ORDERED PRIVATE (A, B, C)
C$OMP THREADPRIVATE(/ABC/)
C$OMP PARALLEL COPYIN(/blk/)
Nthrds = OMP_GET_NUM_PROCS()
!$OMP BARRIER
http://www.openmp.orgLa especificación actual es OpenMP 2.5
250 Páginas
(C/C++ y Fortran)
![Page 19: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/19.jpg)
Arquitectura OpenMP*
Modelo fork-join Bloques de construcción para trabajo en
paralelo Bloques de construcción para el ambiente
de datos Bloques de construcción para sincronización API (Application Program Interface)
extensiva para afinar el control
![Page 20: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/20.jpg)
Modelo de programaciónParalelismo fork-join:
• El hilo maestro se divide en un equipo de hilos como sea necesario
• El Paralelismo se añade incrementalmente: el programa secuencial se convierte en un programa paralelo
Regiones paralelas
Hilo maestro
![Page 21: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/21.jpg)
Sintaxis del Pragma OpenMP*
La mayoría de los bloques de construcción en OpenMP* son directivas de compilación o pragmas.
En C y C++, los pragmas toman la siguiente forma:
#pragma omp construct [clause [clause]…]
![Page 22: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/22.jpg)
Regiones Paralelas
Define una región paralela sobre un bloque de código estructurado
Los hilos se crean como ‘parallel’
Los hilos se bloquean al final de la región
Los datos se comparten entre hilos al menos que se especifique otra cosa
#pragma omp parallel
Hilo
1Hilo
2Hilo
3
C/C++ : #pragma omp parallel
{ bloque
}
![Page 23: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/23.jpg)
¿Cuántos hilos? Establecer una variable de ambiente para el
número de hilos. Ejemplo 4 hilos:
export OMP_NUM_THREADS=4
No hay un default estándar en esta variable En muchos sistemas: # de hilos = # de
procesadores
![Page 24: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/24.jpg)
Ej. 1: Hello World
Modificar el código serial de “Hello, Worlds” para ejecutarse paralelamente usando OpenMP*
int main(){ saludo();}int saludo(){ int i;
for(i=0;i<10;i++) { printf(“Hola mundo desde el hilo principal\n”); sleep(1) }}
![Page 25: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/25.jpg)
Bloques de construcción de trabajo en paralelo
Divide las iteraciones del ciclo en hilos Debe estar en la región paralela Debe preceder el ciclo
#pragma omp parallel#pragma omp for
for (i=0; i<N; i++){Do_Work(i);
}
![Page 26: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/26.jpg)
Bloques de construcción de trabajo en paralelo
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]
![Page 27: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/27.jpg)
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(); }
![Page 28: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/28.jpg)
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 hilo
![Page 29: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/29.jpg)
Ambiente de datos
Pero, no todo es compartido... Las variables en el stack en funciones llamadas de
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
![Page 30: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/30.jpg)
Atributos del alcance de datos
El estatus por default puede modificarsedefault (shared | none)
Clausulas del atributo de alcance
shared(varname,…)
private(varname,…)
![Page 31: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/31.jpg)
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; }}
![Page 32: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/32.jpg)
Ejemplo: producto puntofloat 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?¿Qué es incorrecto?
![Page 33: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/33.jpg)
Proteger datos compartidos
Debe proteger el acceso a los datos compartidos que son modificables
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;}
![Page 34: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/34.jpg)
#pragma omp critical [(lock_name)] Define una región crítica en un bloque estructurado
OpenMP* Bloques de construcción para regiones críticas
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 de condiciones de concurso.
Nombrar las regiones críticas es opcional, pero puede mejorar el rendimiento.
(R1_lock)
(R2_lock)
![Page 35: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/35.jpg)
OpenMP* Cláusula de reducción
reduction (op : list) 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
![Page 36: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/36.jpg)
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]; }
![Page 37: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/37.jpg)
Un rango de operadores asociativos y conmutativos pueden usarse con la reducción
Los valores iniciales son aquellos que tienen sentido
C/C++ Operaciones de reducción
Operador Valor Inicial
+ 0
* 1
- 0
^ 0
Operador Valor Inicial
& ~0
| 0
&& 1
|| 0
![Page 38: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/38.jpg)
Ejemplo de integración numérica4.0
2.0
1.00.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 = %f\n”,pi);}}
![Page 39: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/39.jpg)
Calculando Pi Paralelize 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 = %f\n”,pi);}}
![Page 40: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/40.jpg)
Asignando 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
![Page 41: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/41.jpg)
Asignando Iteracionesschedule(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”
![Page 42: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/42.jpg)
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
Qué planificación utilizar
![Page 43: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/43.jpg)
Ejemplo de la cláusula Schedule#pragma omp parallel for schedule (static, 8) for( int i = start; i <= end; i += 2 ) { if ( TestForPrime(i) ) gPrimesFound++; }
Las iteraciones se dividen en pedazos de 8 Si start = 3, el primer pedazo es
i={3,5,7,9,11,13,15,17}
![Page 44: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/44.jpg)
Secciones paralelas 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();
}
![Page 45: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/45.jpg)
Denota un bloque de código que será ejecutado por un solo hilo
El hilo seleccionado es dependiente de la implementación
Barrera implícita al final
Bloque de construcción Single
#pragma omp parallel{ DoManyThings();#pragma omp single { ExchangeBoundaries(); } // threads wait here for single DoManyMoreThings();}
![Page 46: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/46.jpg)
Denota bloques de código que serán ejecutados solo por el hilo maestro
No hay barrera implícita al final
Bloque de construcción Master
#pragma omp parallel{ DoManyThings();#pragma omp master { // if not master skip to next stmt ExchangeBoundaries(); } DoManyMoreThings();}
![Page 47: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/47.jpg)
Barreras implícitas
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.
![Page 48: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/48.jpg)
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);
![Page 49: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/49.jpg)
Barreras
Sincronización explícita de barreras Cada hilo espera hasta que todos
lleguen#pragma omp parallel shared (A, B, C) {
DoSomeWork(A,B);printf(“Processed A into B\n”);
#pragma omp barrier DoSomeWork(B,C);printf(“Processed B into C\n”);
}
![Page 50: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/50.jpg)
Operaciones Atómicas
Caso especial de una sección crítica Aplica solo para la actualización de
una posición de memoria
#pragma omp parallel for shared(x, y, index, n) for (i = 0; i < n; i++) { #pragma omp atomic x[index[i]] += work1(i); y[i] += work2(i); }
![Page 51: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/51.jpg)
API de OpenMP* Obtener el número de hilo dentro de un equipo
int omp_get_thread_num(void); Obtener el número de hilos en un equipo
int omp_get_num_threads(void); Usualmente no se requiere para códigos de
OpenMP Tiene usos específicos (debugging) Hay que incluir archivo de cabecera
#include <omp.h>
![Page 52: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/52.jpg)
Problemas de rendimiento
Los hilos ociosos no hacen trabajo útil Divide el trabajo entre hilos lo más
equitativamente posible Los hilos deben terminar trabajos paralelos al
mismo tiempo
La sincronización puede ser necesaria Minimiza el tiempo de espera de recursos
protegidos
![Page 53: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/53.jpg)
Cargas de trabajo no balanceadas
Cargas de trabajo desigual produce hilos ociosos y desperdicio de tiempo.
Ocupado Ocioso
#pragma omp parallel{
#pragma omp for for( ; ; ){
}
}
tiempo
![Page 54: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/54.jpg)
#pragma omp parallel{
#pragma omp critical { ... } ...}
Sincronización
Tiempo perdido por locks
tiempo
Ocupado Ocioso En SC
![Page 55: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/55.jpg)
Afinando el rendimiento
Los profilers usan muestreo para proveer datos sobre el rendimiento.
Los profilers tradicionales están limitados para usarse con códigos de OpenMP*:
Miden tiempo del CPU, no tiempo real No reportan contención de objetos de sincronización No pueden reportar carga de trabajo desbalanceada Muchos de ellos no tienen todo el soporte de OpenMP
Los programadores necesitan profilers específicamente diseñadas para OpenMP.
![Page 56: Paradigma “Shared Address Space” Algoritmos paralelos Glen Rodríguez](https://reader035.vdocument.in/reader035/viewer/2022062500/5665b4681a28abb57c9148c5/html5/thumbnails/56.jpg)
Planificación estática: Hacerlo por uno mismo
Debe conocerse: Número de hilos (Nthrds) Cada identificador ID de cada hilo (id)
Calcular iteraciones (start y end):
#pragma omp parallel{
int i, istart, iend;istart = id * N / Nthrds;iend = (id+1) * N / Nthrds;for(i=istart;i<iend;i++){ c[i] = a[i] + b[i];}
}