OpenMP
Enviado por VICTOR EMMANUEL ROMERO HERNÁNDEZ • 6 de Febrero de 2019 • Informe • 2.344 Palabras (10 Páginas) • 511 Visitas
OPENMP:
OpenMP es una interfaz de programación de aplicaciones (API) para la programación multiproceso de memoria compartida en múltiples plataformas. Permite añadir concurrencia a los programas escritos en C, C++ y Fortran sobre la base del modelo de ejecución fork-join. Está disponible en muchas arquitecturas, incluidas las plataformas de Unix y de Microsoft Windows. Se compone de un conjunto de directivas de compilador, rutinas de biblioteca, y variables de entornoque influyen el comportamiento en tiempo de ejecución.
Definido conjuntamente por proveedores de hardware y de software, OpenMP es un modelo de programación portable y escalable que proporciona a los programadores una interfaz simple y flexible para el desarrollo de aplicaciones paralelas, para plataformas que van desde las computadoras de escritorio hasta supercomputadoras. Una aplicación construida con un modelo de programación paralela híbrido se puede ejecutar en un cluster de computadoras utilizando OpenMP y MPI, o a través de las extensiones de OpenMP para los sistemas de memoria distribuida.
Apuntes:
Compilar: gcc -fopenmp hola.c
Utiliza directivas llamadas constructores y clausulas, las cláusulas se utilizan siempre después de un constructor
Sintaxis
#pragma omp construtor
{
}
Constructor parallel
Define una región paralela, genera un numero de hilos
#include
#include
//omp_set_num_threads(3);
main(){
int i, nth, id;
#pragma omp parallel private(id)
{
nth = omp_get_num_threads();
id = omp_get_thread_num();
printf("Hola world");
#pragma omp for
for(i=0; i<10; i++){
printf("\n iter %d , %d ", i, id );
}
}
printf ("\n Adiós");
//printf("%d", i);
return 0;
}
Imprimir del 1 hasta el 10 pero cada impresión tiene un hilo asociado
Variables privadas y compartidas
Las variables declaradas fuera de una región paralela son compartidas entre los hilos
Las variables declaradas dentro de una región paralela son propias de cada hilo (privadas)
Las variables privadas tienen un valor indefinido fuera de la región paralela
- shared(valor-i_1, ..., valor-i_N): Los datos de la región paralela son compartidos, lo que significa que son visibles y accesibles por todos los hilos. Por definición, todas las variables que trabajan en la región paralela son compartidas excepto el contador de iteraciones.
- private(valor-i_1, ..., valor-i_N): Los datos de la región paralela nombrados por private son copiados al área de almacenamiento local del hilo (principalmente su pila), lo que significa que cada hilo los usará como variable temporal. Una variable privada no es inicializada y tampoco se mantiene fuera de la región paralela. Por definición, el contador de iteraciones en OpenMP es privado.
#pragma omp parallel private(id,i , n)
{
#pragma omp for
id = omp_get_thread_num();
inicio = id * 5;
fin = (id + 1 )*5;
//for(i= inicio;i
for(i= 0;i< n ;i++)
{
c[i] = a[i] + b[i];
printf("\n nc %d calculado por el hilo : %d\n",i,id);
}
}
}
El estatus por default puede modificarse
default (shared | none)
Clausulas del atributo de alcance
shared(varname,…) La variable es compartida por todos los procesos
private(varname,…)
Cada proceso tiene una copia de la variable
#pragma omp parallel for shared(a,b,c,n) private(i)
for (i = 0; i < n; i++) {
a(i) = b(i) + c(i);
}
Construtor For
for: El equipo de hilos que se encuentra con el for ejecuta una o más fracciones de iteraciones como resultado de dividir el bucle delimitado por la directiva entre los hilos del equipo (el tamaño de cada partición dependerá de las cláusulas opcionales añadidas al for). Su formato es:
#pragma omp parallel for [cláusula, ... , cláusula]
[pic 1]
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.
Cláusulas de Planificación (Scheduling)
schedule(omp_sched_t tipo, int chunk_size): Esto es útil si la carga procesal es un bucle do o un bucle for. Las iteraciones son asignadas a los threads basándose en el método definido en la cláusula. Los tres tipos de scheduling son:
- static: Aquí todas las iteraciones se reparten entre los threads antes de que estos ejecuten el bucle. Se reparten las iteraciones contiguas equitativamente entre todos los threads. Especificando un integer como parámetro de chunk serán repartidas tantas iteraciones contiguas al mismo thread como el chunk indique.
- dynamic: Aquí al igual que en static se reparten todas las iteraciones entre los threads. Cuando un thread en concreto acaba las iteraciones asignadas, entonces ejecuta una de las iteraciones que estaban por ejecutar. El parámetro chunk define el número de iteraciones contiguas que cada thread ejecutará a la vez.
- guided: Un gran número de iteraciones contiguas son asignadas a un thread. Dicha cantidad de iteraciones decrece exponencialmente con cada nueva asignación hasta un mínimo especificado por el parámetro chunk.
Si no se pone ninguna clausula schedule, la planificacion por defecto es schedule(static,1). Esto es, se reparten las iteraciones del bucle de forma round-robin de una en una.
...