Está en la página 1de 12

Programación paralela

Año 2019
OpenMP

Es una API para realizar explícitamente paralelismo multithreaded de memoria compartida.

Tiene tres componentes:


directivas al compilador,
rutinas en tiempo de ejecución
variables de entorno.

Es un estándar y es portable.

Se basa en el modelo fork-join, paradigma que proviene de los sistemas Unix, donde una tarea muy pesada se
divide en K hilos (fork) con menor peso, para luego "recolectar" sus resultados al final y unirlos en un solo
resultado (join)

Inicialmente se ejecuta un thread hasta que aparece el primer constructor paralelo, se crean threads esclavos y
el que los pone en marcha es el maestro.
Al final del constructor se sincronizan los threads y continúa la ejecución el maestro.
Open mp en windows
• se instala cygwin
• compilador c (gcc-core) y compilador de c++
• Una utilidad make( make.exe)
• Depurador (gdb)
• En propiedades del proyecto se coloca en aplicación –fopenmp
• Tools_pluggins-gdbserver
• En las variables del entorno, se edita y se agrega el directorio de
cygwin
Librería #include <omp.h>
Funciones
omp_set_num_threads: Fija el número de hilos simultáneos.
omp_get_num_threads: Devuelve el número de hilos en ejecución.
omp_get_max_threads: Devuelve el número máximo de hilos que lanzará nuestro programa en las zonas
paralelas. Es muy útil para reservar memoria para cada hilo.
omp_get_thread_num: Devuelve el número del thread dentro del equipo (valor
entre 0 y omp_get_num_threads()-1)
omp_get_num_procs: Devuelve el número de procesadores de nuestro ordenador o disponibles (para
sistemas virtuales).
omp_set_dynamic: Valor booleano que nos permite especificar si queremos que el número de hilos crezca y
decrezca dinámicamente.
Directivas
También se suelen llamar constructores:
parallel: Esta directiva nos indica que la parte de código que la
comprende puede ser ejecutada por varios hilos.
for: Igual que parallel pero optimizado para los bucles for. Su formato
es:
#pragma omp parallel for [cláusula, ... , cláusula]
El equipo de hilos que se encuentra con el for ejecuta una o mas
fracciones de iteraciones como resultado de dividir el bucle delimitado
por la directiva entre los hilos del equipo.
b. Código de un programa en C que utiliza la biblioteca omp.h.

#include<stdio.h>
#include <omp.h>

main () {
int nthreads, tid;
#pragma omp parallel
{
/* Obtiene número de hilo */
tid = omp_get_thread_num();
printf("Hola Mundo desde el hilo = %d\n",tid);
/* Only master thread does this */
if (tid == 0)
{
nthreads = omp_get_num_threads();
printf("Numero de hilo = %d\n", nthreads);
}} }
#include <stdio.h>
#include <omp.h>
int main(){
int numeroHilos;
printf("Ingresar el numero de hilos: ");
scanf("%d", &numeroHilos);
int numeroProcesadores = omp_get_num_procs();
omp_set_num_threads(numeroHilos);
printf("Este computador usa %d procesador(es)\n", numeroProcesadores);
printf("En este ejemplo se desea usar %d hilo(s)\n", omp_get_max_threads());
printf("En este momento se esta(n) ejecutando %d hilo(s)\n", omp_get_num_threads());
printf("\nAcabo de entrar a la seccion paralela\n");
#pragma omp parallel
{ int idHilo = omp_get_thread_num();
printf("Hola, soy el hilo %d, en este momento se esta(n) ejecutando %d hilo(s)\n", idHilo,
omp_get_num_threads());
} printf("Acabo de salir de la seccion paralela\n");
printf("\nEn este momento se esta(n) ejecutando %d hilo(s)\n", omp_get_num_threads());
return 0;}
Código para la multiplicación de dos vectores

#include<omp.h>
#include<stdio.h>
#include<stdlib.h>
int main (int argc,char *argv[]){

int i,n;
float a[100],b[100],sum;
N=100;
For(i=0;i<n;i++)
A[i]=b[i]=i*1,0;
Sum=0,0;
#pragma omp parallel for reduction(+:sum)
for(i=0;i<n;i++)
sum=sum+(a[i]*b[i]);
printf(“suma=%f\n”,sum);
}
#pragma omp parallel for reduction(+:sum)

los bucles que representan una reducción son


bastante comunes.
Por lo tanto, OpenMP tiene la reduction cláusula
especial que puede expresar la reducción de un
bucle for.
Para especificar la reducción en OpenMP, debemos
proporcionar
una operación ( +/ */ o)
y una variable de reducción( sum/ product/ reduction).
Esta variable guarda el resultado del cálculo.
#include<omp.h>
#include<stdio.h>
#include<stdlib.h>

int main(int argc, char** argv) {


int nhilos, tid;
#pragma omp parallel private(tid)
{
tid = omp_get_thread_num();
nhilos = omp_get_num_threads();
printf("hola desde el thread %d de %d threads\n", tid, nhilos);
}
return (EXIT_SUCCESS);
}
• #pragma omp parallel private(tid)
• Una región paralela es un trozo de código que se va a repetir en todos los
threads. Las variables de una región paralela pueden ser compartidas (de
todos los threads, shared) o privadas (diferentes para cada thread). El
ámbito de las variables se define mediante cláusulas específicas.
• #pragma omp taskwait//El hilo instanciador de tareas se queda esperando
en el taskwait hasta que todas las tareas previas al taskwait hayan
terminado su ejecución.
• #pragma omp task shared(fn1)//El bloque de código dentro de la directiva
task es ejecutado por un único hilo, y la tarea es instanciada por el hilo que
se encuentra con la directiva.shared:Los datos de la región paralela son
compartidos, lo que significa que son visibles y accesibles por todos los
hilos.
• #pragma omp single//una tarea específica para un único thread dentro de
una región paralela
Ejercicio de Fibonacci
#include<omp.h> printf("\n Numero a calcular? ");
#include<stdio.h> scanf("%d", &n);
#include<stdlib.h>
long fibonacci(int n)
{ long fn1, fn2, fn;
#pragma omp parallel shared (resul)
{
if ( n == 0 || n == 1 ) return(1);
#pragma omp single
// if ( n < 30 ) return(fibonacci(n-1) + fibonacci(n-2));
{
#pragma omp task shared(fn1) resul = fibonacci(n);
fn1 = fibonacci(n-1); }
#pragma omp task shared(fn2) }
fn2 = fibonacci(n-2);
printf ("\nEl numero Fibonacci de %5d es %d", n, resul);
#pragma omp taskwait
fn = fn1 + fn2;
tej = (t1.tv_sec - t0.tv_sec) + (t1.tv_usec - t0.tv_usec) / 1e6;
return(fn); } printf("\n T. de ejec. = %1.3f ms \n\n", tej*1000);
main () }
{ struct timeval t0, t1;
double tej;
int nthr=0;
int n;
long resul;

También podría gustarte