Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el...

31
Arquitectura de Computadores Arquitectura de Computadores: Arquitectura de Computadores Arquitectura de Computadores: Práctica de Multiprocesadores Práctica de Multiprocesadores Introducción a Introducción a OpenMP OpenMP

Transcript of Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el...

Page 1: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

Arquitectura de ComputadoresArquitectura de Computadores::Arquitectura de ComputadoresArquitectura de Computadores::

Práctica de MultiprocesadoresPráctica de Multiprocesadores

Introducción a Introducción a OpenMPOpenMP

Page 2: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

ÍndiceÍndice

1 Introducción1. Introducción 2. Regiones Paralelas: 3. Distribución del trabajo4. Gestión de datos5. Sincronización6 F i d bibli t6. Funciones de biblioteca7. Variables del entorno8. Ejemplo Π

AC : MP: Introd. a OpenMP 2

Page 3: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

¿Qué es OpenMP?¿Qué es OpenMP?API estándar “de facto” para la programación multithread desistemas de memoria compartida (C, C++ y Fortran)

Consta de:

● Directivas para el compilador● Directivas para el compilador● Funciones de librería● Variables de entorno● Variables de entorno

AC : MP: Introd. a OpenMP 3

Page 4: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

IntroducciónIntroducción OpenMP se basa en directivas al compilador (¡el código es

compilable incluso si el compilador no soporta OpenMP!)p p p p )

Que se aplican a “bloques estructurados”: una o más sentencias con un punto de entrada y uno de salidap y

Se apoya en threads, para la paralelización (modelo SPMD)

O MP b l l li ió d b l (d ) OpenMP se basa en la paralelización de bucles (datos)

Mismo código fuente para secuencial y paraleloSe protege con el preprocesador: #ifdef _OPENMP ….

Los prototipos de funciones y los tipos están en el fichero:p p y p#include <omp.h>

¡Puede haber interbloqueos y carreras!

AC : MP: Introd. a OpenMP 4

¡ q y También soporta vectorización y coprocesadores

Page 5: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

Modelo de programación de OpenMPModelo de programación de OpenMP

Modelo de paralelismo: Fork-Join El programa comienza con un solo thread (maestro) El maestro crea threads según necesidad

AC : MP: Introd. a OpenMP 5

Page 6: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

EjemploEjemplo

// Secuencial:void main(){

// Paralelo:void main(){{

double Res[1000];{

double Res[1000];

for(int i=0;i<1000;i++)do huge comp(Res[i]);

#pragma omp parallel forfor(int i=0;i<1000;i++)

do huge comp(Res[i]);_ g _ p}

_ g _ p}

Similar la versión paralela y la secuencialSimilar la versión paralela y la secuencial. Pocos cambios, legible y fácil de mantener

ACAR: Introducción a OpenMP 6

Page 7: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

Creación de threads: Regiones ParalelasCreación de threads: Regiones ParalelasSe declaran con la directiva

# ll l [ lá l ]#pragma omp parallel [cláusulas] {//código…}

Crea N threads que ejecutan en paralelo el mismo código, solo cambia su ID.

¡Al final de la región hay una barrera implícita!

El número de threads depende de variables internas p(num_threads, max_threads, dynamic)

o de la cláusula num threads(int)o de c usu u _t eads( t)

Si se pone la cláusula if, se paraleliza sólo si se cumple la condición:…parallel if(N>100)…

AC : MP: Introd. a OpenMP 7

condición:…parallel if(N>100)…

Page 8: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

Regiones Paralelas: EjemploRegiones Paralelas: Ejemplo

#include “omp.h”#include omp.h…………

double A[1000];

Funciones de librería

double A[1000];omp_set_num_threads(4);#pragma omp parallel#pragma omp parallel{

int ID = omp get thread num();int ID = omp_get_thread_num();sumarElemA (ID,A);

}}

Cada thread llama a sumarElemA para ID=0 .. 3l i d A id d l h d

AC : MP: Introd. a OpenMP 8

Una sola copia de A, compartida por todos los threads

Page 9: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

Regiones Paralelas: EjemploRegiones Paralelas: Ejemplo

#include “omp.h”#include omp.h…………

double A[1000]; cláusuladouble A[1000];

#pragma omp parallel num threads(4)#pragma omp parallel num_threads(4){

int ID = omp get thread num();int ID = omp_get_thread_num();sumarElemA (ID,A);

}}

Cada thread llama a sumarElemA para ID=0 .. 3l i d A id d l h d

AC : MP: Introd. a OpenMP 9

Una sola copia de A, compartida por todos los threads

Page 10: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

Distribución del trabajo: forDistribución del trabajo: for

Se declara con la directiva#pragma omp for [cláusulas]for (;;) {//código…}for (;;) {//código…}

Divide las iteraciones de un bucle entre los threadsdi ibldisponibles.

Al final hay una barrera implícita,evitable con cláusula nowait

Se puede especificar cómo se reparten las iteraciones entre Se puede especificar cómo se reparten las iteraciones entre los threads:

cláusula schedule

AC : MP: Introd. a OpenMP 10

cláusula schedule

Page 11: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

Distribución del trabajo for: EjemploDistribución del trabajo for: Ejemplo

1. Código secuencial for(i=0;i<N;i++) g

#pragma omp parallel{

{a[i] = a[i] + b[i];}

2. Región Paralela OpenMPdi ib ió d b j {

int id, i,Nthrds,istart,iend;id = omp_get_thread_num();Nthrds =omp get num threads();

distribución de trabajo manualmente(id, i, Nthrds, Nthrds omp_get_num_threads();

istart = id * N / Nthrds;iend = (id+1) * N / Nthrds;for(i=istart;i<iend;i++)

istart, iend: son variables privadas, ¿por qué? ¿deben serlo?)

3 R ió P l l O MP

( ){ a[i] = a[i] + b[i];}

}

¿p q ¿ )

#3. Región Paralela OpenMP y distribución de trabajo for

#pragma omp parallel#pragma omp for schedule(static)for(i=0;i<N;i++) { [i] [i] + b[i] }

AC : MP: Introd. a OpenMP 11

{ a[i] = a[i] + b[i];}

Page 12: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

Distribución del trabajo for: PlanificaciónDistribución del trabajo for: PlanificaciónPlanificación con la cláusula schedule:

##pragma omp for schedule(..)

schedule (static [,chunk])Asigna bloques fijos de iteraciones de tamaño “chunk” a cada thread

schedule (dynamic [,chunk])C d h d “ h k” i i h i dCada thread coge “chunk” iteraciones hasta terminar con todas

schedule (guided [,chunk])C d th d di á i t bl d it i● Cada thread coge dinámicamente bloques de iteraciones

● El bloque inicialmente es grande (nº iteraciones sin asignar dividido por nº threads) y va bajando hasta tamaño“chunk”

schedule (runtime)Planificación y tamaño de bloque determinado por la variable de entorno OMP SCHEDULE

AC : MP: Introd. a OpenMP 12

entorno OMP_SCHEDULE

Page 13: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

Planificación: Ejemploj p200 iteraciones en 4 threads

AC : MP: Introd. a OpenMP 13

Page 14: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

Distribución del trabajo: sectionsDistribución del trabajo: sections

Asigna bloques de código a threadsAsigna bloques de código a threads.

Ejemplo:#pragma omp parallel#pragma omp sections{{x_calculation();

#pragma omp sectiony_calculation();

#pragma omp sectionz calculation();_ ();

}

Al final hay una barrera (evitable con nowait)

AC : MP: Introd. a OpenMP 14

Page 15: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

Gestión de los datosGestión de los datos

Modelo de programación de memoria compartida:Modelo de programación de memoria compartida:● La mayoría de las variables son compartidas por defecto● Las variables globales son compartidasLas variables globales son compartidas

Pero no todas las variables son compartidas:Al d b ífi d h d● Algunas deben ser específicas para cada thread

● Las variables declaradas dentro de una región paralela

● Las ubicadas en cada pila propia (parámetros y variables locales) son privadas (cada thread tiene su pila)

Se puede cambiar los ‘atributos’ de las variables heredadas del maestro mediante cláusulas

AC : MP: Introd. a OpenMP 15

Page 16: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

Gestión de los datosGestión de los datos

shared: Variable común a todos los threadsshared: Variable común a todos los threadsCuidado: puede ser necesario utilizar regiones críticas

i t C d h d ti “ ” i l l private: Cada thread tiene “su” copia local. Sin inicializar y valor indefinido tras la región paralela

firstprivate: Es “private”, pero se inicializa con el valor de la ‘original’ (variable del maestro)

lastprivate: Es “private”, pero al final se le asigna el valor que toma en la última iteración o sección

default: shared, private (FORTRAN) o none

AC : MP: Introd. a OpenMP 16

Page 17: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

Gestión de los datosGestión de los datos threadprivate: hace una copia de una variable, privada

d h d i l l d l j ió (para cada thread. Existe a lo largo de la ejecución (en secuencial se ve la copia del maestro)

copyin: inicializa las variables threadprivate con el valor de la del maestro

copyprivate: pasa el valor dado por un thread al resto (se usa con single)

reduction (op:list): deben ser variables shared• Hará una copia local y la inicializará según “op”• Al final las copias locales se reducen a una global• Operadores: + * - & | ^ && || min max

AC : MP: Introd. a OpenMP 17

Page 18: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

Gestión de los datos: Ejemplosj p1. int tmp=0;

#pragma omp parallel private(i) firstprivate(tmp)#pragma omp parallel private(i) firstprivate(tmp){ i = 3 + func(id);tmp = tmp + 2;}

2. #pragma omp parallel for lastprivate(i)for (i=0; i<n-1; i++)

a[i] = b[i] + b[i+1a[i]=b[i]; // caso n-1 fuera bucle

3. double ave=0.0, A[MAX], int i;#pragma omp parallel for \

h d l ( t ti ) d ti ( )schedule (static)reduction(+:ave)for (i=0; i<MAX; i++)

ave+= A[i];/MAX

AC : MP: Introd. a OpenMP 18

ave = ave/MAX

Page 19: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

Gestión de los datosGestión de los datos1. int counter = 0; // Nº tareas ejecutadas por cada hilo…

#pragma omp threadprivate(counter)

2 #pragma omp threadprivate(work size)2. #pragma omp threadprivate(work,size)

#pragma omp parallel copyin(size) shared(N){

work = build(tol,size+N);}

3. #pragma omp parallel for reduction(+:res) lastprivate(Z,i)for (i=0; i< 1000; i++){

Z = func(I);Z = func(I);res = res + Z;

}

ACAR: Introducción a OpenMP 19

Page 20: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

SincronizaciónSincronización

critical [name]: Definición de una región crítica.critical [name]: Definición de una región crítica.Los threads esperan al comienzo de la región crítica hasta que no

haya ningún hilo ejecutando una región crítica con el mismo b T d l ti b id tinombre. Todas las que no tienen nombre, se consideran que tienen

un mismo nombre no especificado

Atomic [read|write|update|capture]: Asegura una actualización atómica. Por defecto update

L t tó i● Lectura atómica: v = x;● Escritura atómica: x = expr; //expr no atómica● Actualización atómica: x = x binop expr;● Actualización atómica: x x binop expr;● “Captura” atómica: v = x binop= expr; // x atómico

AC : MP: Introd. a OpenMP 20

Page 21: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

SincronizaciónSincronización

barrier: Implementa una barrerabarrier: Implementa una barrera

ordered: Asegura que las iteraciones se ejecutan en el mismo orden que en secuencial: ¡¡evítese en lo posible!!mismo orden que en secuencial: ¡¡evítese en lo posible!!

master: Sólo el maestro ejecuta dicho código, los demás se lo saltan. Sin barrera.

single: Un solo thread ejecuta dicho código, tiene una barrera g j g ,implícita. Con copyprivate puede hacer visible a los demás threads los cálculos hechos.

AC : MP: Introd. a OpenMP 21

Page 22: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

Sincronización: EjemplosSincronización: Ejemplos1. #pragma omp parallel for schedule(dynamic) private(a)

for (i=0; i<N; i++){a = work(i); // en paralelo

#pragma omp ordered // espera que le toqueprintf(“%d\n", a); //impresión resultados ordenadaprintf( %d\n , a); //impresión resultados ordenada

}2. #pragma omp threadprivate(x, y)

void init(float a float b ) { // a y b privadosvoid init(float a, float b ) { // a y b privados#pragma omp single copyprivate(a,b,x,y)

scanf("%f %f %f %f", &a, &b, &x, &y); }}

3. #pragma omp critical qlockenqueue(job);

…#pragma omp critical qlock

dequeue(job);

AC : MP: Introd. a OpenMP 22

Page 23: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

SincronizaciónSincronización

1. omp_lock_t *new_lock()_ _ _{omp_lock_t *lock_ptr;#pragma omp single copyprivate(lock_ptr){lock_ptr = (omp_lock_t *)malloc(sizeof(omp_lock_t));omp_init_lock( lock_ptr );//} //barrera, todos salen con el cerrojo!!!

return lock_ptr;}

AC : MP: Introd. a OpenMP 23

Page 24: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

TareasTareas

A partir de OpenMP 3 0A partir de OpenMP 3.0

Permite definir una “task”: conjunto de código y datos j ta ejecutar:

#pragma omp task firstprivate(my_pointer)

(void) do independent work (my pointer);(void) do_independent_work (my_pointer);

Si hay algún thread disponible se pone a ejecutarla, si no espera uno libre.no espera uno libre.

Se espera por ellas en las barreras implícitas y explícitasexplícitas

2424ACAR: Introducción a OpenMP

Page 25: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

OpenMP 4 0OpenMP 4.0 Está disponible OpenMP 4.0 (http://www.openmp.org) Dos cambios importantes: vectorización y coprocesadores Vectorización: nuevo #pragma omp simd para vectorizar

bucles. Toma la idea de Intel (icc). Con claúsulas● Busca aprovechar las unidades vectoriales: MMX, SSE, AVX,

MIC) Se podrá combinar con regiones paralelas:MIC). Se podrá combinar con regiones paralelas:#pragma omp parallel for simd

Coprocesadores: Se busca aprovechar las GPUs y MICs de Coprocesadores: Se busca aprovechar las GPUs y MICs, de gran potencia de cálculo. ● Se introduce #pragma omp target para indicar elSe introduce #pragma omp target para indicar el

dispositivo sobre el que se quiere ejecutar ● Toma la idea de PG, que ya dispone del OpenACC, un

ACAR: Introducción a OpenMP 25

OpenMP de pago para GPUs

Page 26: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

Funciones de biblioteca: Entorno de Ejecución

Gestión de threadsGestión de threads• void omp_set_num_threads(int)• int omp get num threads(void)t o p_get_ u _t eads( o d)• int omp_get_thread_num(void)• int omp_get_max_threads(void)_ _ _• void omp_set_dynamic(bool)• bool omp_get_dynamic(void)

Anidamiento del paralelismo• void omp set nested(bool)void omp_set_nested(bool)• bool omp_get_nested(void)

AC : MP: Introd. a OpenMP 26

Page 27: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

Funciones de biblioteca: Entorno de Ejecución y Cerrojos

CerrojosCerrojos• void omp_init_lock(lock)• void omp_destroy_lock(lock)• void omp_set_lock(lock)• void omp_unset_lock(lock)

oid omp test lock(lock)• void omp_test_lock(lock) ¿En una región paralela?

bool omp in parallel(void)bool omp_in_parallel(void)

Número procesadores:int omp num procs(void)int omp_num_procs(void)

Tomar tiemposomp get wtime(), omp get wtick()

AC : MP: Introd. a OpenMP 27

p_g _ p_g _

Page 28: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

Variables del Entorno del EjecuciónVariables del Entorno del Ejecución

OMP SCHEDULE “schedule[, chunk size]”OMP_SCHEDULE schedule[, chunk_size]

OMP_NUM_THREADS int_literal // Máximo

b l // j l ú d OMP_DYNAMIC bool //Ajusta el número de hilos en cada región paralela

OMP_NESTED bool

OMP_PROC_BIND bool

OMP_STACKSIZE int [B|K|M|G}

OMP WAIT POLICY passive || activeOMP_WAIT_POLICY passive || active

OMP_THREAD_LIMIT int

AC : MP: Introd. a OpenMP 28

Page 29: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

CompilaciónCompilación

Incluir el fichero de cabecera: #include <omp.h>p

Se activa _OPENMP

Compilador de GCC:gcc -fopenmpgfortran -fopenmp

Compilador de Intel:Compilador de Intel:icc -openmpifort –openmp

AC : MP: Introd. a OpenMP 29

Page 30: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

Ejemplo del cálculo de PiEjemplo del cálculo de Pi Por cálculo númerico:

dx

x1

0 210.4

Se aproxima como:

x0 1

xxFN

i )(

con F(xi) el alto a mitad del

i 0

intervalo y x el ancho del intervalo

AC : MP: Introd. a OpenMP 30

Page 31: Introducción a Introducción a OpenMPOpenMP · OpenMP se basa en directivas al compilador (¡el código es comppppp)ilable incluso si el compilador no soporta OpenMP!) Que se aplican

Ejemplo del cálculo de Pi : SecuencialEjemplo del cálculo de Pi : Secuencial

static long num_steps = 100000;double step;void main (){void main (){

int i; double x, pi, 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;pi = step sum;

}

AC : MP: Introd. a OpenMP 31