openmp Tutorial
Empezando con openmp
Buscar..
Observaciones
OpenMP (Open MultiProcessing) es un modelo de programación paralelo basado en directivas de compilación que permite a los desarrolladores de aplicaciones agregar progresivamente paralelismo a sus códigos de aplicación.
La especificación de API OpenMP para programación paralela proporciona una interfaz de programación de aplicaciones (API) que admite la programación multiprocesamiento de memoria compartida multiplataforma en C, C ++ y Fortran, en la mayoría de las plataformas. Consiste en un conjunto de directivas de compilación, rutinas de biblioteca y variables de entorno que influyen en el comportamiento en tiempo de ejecución.
Dado que OpenMP se centra en el paralelismo dentro de un nodo (multiprocesamiento de memoria compartida), se puede combinar con modelos de programación de paso de mensajes, como MPI, para ejecutar en múltiples nodos.
Versiones
Versión | Idioma | Fecha de lanzamiento |
---|---|---|
4.5 | C / C ++ / Fortran | 2015-11-01 |
4.0 | C / C ++ / Fortran | 2013-07-01 |
3.1 | C / C ++ / Fortran | 2011-07-01 |
3.0 | C / C ++ / Fortran | 2008-05-01 |
2.5 | C / C ++ / Fortran | 2005-05-01 |
2.0c | C / C ++ | 2002-03-01 |
2.0f | Fortran | 2000-11-01 |
1.0c | C / C ++ | 1998-10-01 |
1.0f | Fortran | 1997-10-01 |
Compilacion
Hay muchos compiladores que soportan diferentes versiones de la especificación OpenMP. OpenMP mantiene una lista aquí con el compilador que lo admite y la versión compatible. En general, para compilar (y vincular) una aplicación con soporte OpenMP solo necesita agregar un indicador de compilación y, si usa la API de OpenMP, debe incluir el encabezado de OpenMP (omp.h). Mientras que el archivo de encabezado tiene un nombre fijo, el indicador de compilación depende del compilador. La siguiente es una lista no exhaustiva de compiladores y la bandera que habilita OpenMP.
- GCC (incluidos gcc, g ++ y gfortran):
-fopenmp
- LLVM: -fopenmp
- Compilador-suite de Intel (incluidos icc, icpc e ifort):
-qopenmp
(y-fopenmp
para compatibilidad con GCC / LLVM) - IBM XL compilador-suite (incluyendo xlc, xlC y xlf):
-xlsmp=omp
- PGI compiler-suite (incluyendo pgcc pgc ++ pgfortran): '-mp'
Mundo paralelo de hola usando OpenMP
#include <omp.h>
#include <stdio.h>
int main (int argc, char *argv[])
{
#pragma omp parallel
{
printf ("Hello world! I'm thread %d out of %d threads.\n",
omp_get_thread_num(), omp_get_num_threads());
}
return 0;
}
Este código simplemente crea un equipo de subprocesos (de acuerdo con la variable de entorno OMP_NUM_THREADS
, y si no se define, creará uno por núcleo lógico en el sistema) y cada subproceso se identificará además de imprimir el mensaje típico de Hello World.
Construcción de trabajo compartido - Ejemplo de bucle For
double res[MAX]; int i;
#pragma omp parallel
{
#pragma omp for
for (i=0;i< MAX; i++) {
res[i] = huge();
}
}
El bucle for se ejecutará en paralelo. enorme () es un método que puede tardar mucho tiempo en ejecutarse. OpenMP admite un acceso directo para escribir el código anterior como:
double res[MAX]; int i;
#pragma omp parallel for
for (i=0;i< MAX; i++) {
res[i] = huge();
}
También podemos tener una cláusula de programación que afecta la forma en que las iteraciones de bucle se asignan a los hilos. Por ejemplo:
#pragma omp parallel
#pragma omp for schedule(static)
for(i=0;I<N;i++) {
a[i] = a[i] + b[i];
}
Los diferentes estilos de programación son:
horario (static [, chunk])
Repartiendo bloques de iteraciones de tamaño "trozo" a cada hilo.
Si no se especifica: asigne lo más equitativamente posible a los subprocesos disponibles
horario (dinámico [, chunk])
Cada subproceso toma iteraciones "trozos" de una cola hasta que se hayan manejado todas las iteraciones.
horario (guiado [, chunk])
Los hilos agarran dinámicamente bloques de iteraciones. El tamaño del bloque comienza en grande y se reduce a tamaño "trozo" a medida que avanza el cálculo.
horario (tiempo de ejecución)
Horario de planificación y tamaño tomado de la variable de entorno OMP_SCHEDULE.
Ejemplo de reducción
#include <omp.h>
void main ()
{
int i;
double ZZ, func(), res=0.0;
#pragma omp parallel for reduction(+:res) private(ZZ)
for (i=0; i< 1000; i++){
ZZ = func(I);
res = res + ZZ;
}
}
En la última línea: en realidad se agrega a una copia privada, luego se combina después del bucle. El compilador cuida los detalles.