Vous êtes sur la page 1sur 55

26/6/2018 OpenMP

Traducido al: español Mostrar texto original Opciones ▼

Tutoriales | Ceremonias | Resúmenes | Talleres LC | Comentarios | Buscar | Privacidad y aviso legal

OpenMP
Autor: Blaise Barney, Laboratorio Nacional Lawrence Livermore UCRL-MI-133316

Tabla de contenido
1. Abstracto
2. Introducción
3. Modelo de programación OpenMP
4. Descripción general de la API OpenMP
5. Compilación de programas OpenMP
6. Directivas OpenMP
1. Formato directivo
2. Formato de la directriz C / C ++
3. Alcance Directivo
4. Construcción PARALELA
5. Ejercicio 1
6. Construcciones de trabajo compartido
1. DO / para la Directiva
2. SECCIONES Directiva
3. SINGLE Directiva
7. Construcciones combinadas de trabajo compartido en paralelo
8. TASK Construct
9. Ejercicio 2
10. Construcciones de sincronización
1. Directiva MASTER
2. Directiva CRÍTICA
3. Directiva BARRERA
4. Directiva TASKWAIT
5. Directiva ATOMIC
6. Directiva FLUSH
7. PEDIDO Directiva
11. Directiva THREADPRIVATE
12. Cláusulas de atributos de alcance de datos
1. Cláusula PRIVADA
2. Cláusula COMPARTIDA
3. Cláusula DEFAULT
4. Cláusula FIRSTPRIVATE
5. Cláusula LASTPRIVATE
6. Cláusula COPYIN
7. Cláusula COPYPRIVATE
8. Cláusula REDUCCIÓN
13. Resumen de cláusulas / directivas
14. Reglas vinculantes y anidamiento de directivas
7. Rutinas de biblioteca en tiempo de ejecución
8. Variables de entorno
9. Tamaño de pila de subprocesos y enlace de subprocesos
10. Herramientas de monitoreo, depuración y análisis de rendimiento para OpenMP
11. Ejercicio 3
12. Referencias y más información
13. Apéndice A: Rutinas de biblioteca en tiempo de ejecución

Abstracto

OpenMP es una interfaz de programa de aplicación (API), definida conjuntamente por un grupo de principales proveedores de
hardware y software. OpenMP proporciona un modelo portátil y escalable para desarrolladores de aplicaciones paralelas de
memoria compartida. La API admite C / C ++ y Fortran en una amplia variedad de arquitecturas. Este tutorial cubre la mayoría de
https://computing.llnl.gov/tutorials/openMP/ 1/55
26/6/2018 OpenMP
las características principales de OpenMP 3.1, incluidas sus diversas construcciones y directivas para especificar regiones

paralelas, intercambio de trabajo, sincronización y entorno de datos. Las funciones de la biblioteca de tiempo de ejecución y las
variables de entorno también están cubiertas. Este tutorial incluye códigos de ejemplo de C y Fortran y un ejercicio de laboratorio.

Nivel / Prerrequisitos: Este tutorial es ideal para aquellos que son nuevos en la programación paralela con OpenMP. Se requiere
una comprensión básica de la programación paralela en C o Fortran. Para aquellos que no están familiarizados con la
programación paralela en general, el material cubierto en EC3500: Introducción a la computación en paralelo sería útil.

Introducción

¿Qué es OpenMP?
OpenMP es:

Una interfaz de programa de aplicación (API) que se puede usar para dirigir explícitamente el
paralelismo de memoria compartida de subprocesos múltiples .

Compuesto de tres componentes principales de API:


Directivas del compilador
Rutinas de la biblioteca de tiempo de ejecución
Variables de entorno

Una abreviatura para: Abrir Multi-Procesamiento

OpenMP no es:

Significa para sistemas paralelos de memoria distribuida (por sí mismo)

Necesariamente implementado de forma idéntica por todos los proveedores

Garantizado para hacer el uso más eficiente de la memoria compartida

Se requiere para verificar dependencias de datos, conflictos de datos, condiciones de carrera, interbloqueos o secuencias de
códigos que hacen que un programa se clasifique como no conforme.

Diseñado para manejar E / S paralelas. El programador es responsable de sincronizar la entrada y la salida.

Objetivos de OpenMP:

Normalización:
Proporcionar un estándar entre una variedad de arquitecturas / plataformas de memoria compartida
Definido y avalado conjuntamente por un grupo de importantes proveedores de hardware y software

Clara y directa:
Establezca un conjunto simple y limitado de directivas para programar máquinas de memoria compartida.
Se puede implementar un paralelismo significativo usando solo 3 o 4 directivas.
Este objetivo es cada vez menos significativo con cada nuevo lanzamiento, al parecer.

Facilidad de uso:
Proporcionan la capacidad de paralelizar incrementalmente un programa en serie, a diferencia de las bibliotecas de
paso de mensajes que generalmente requieren un enfoque de todo o nada.
Proporcionar la capacidad de implementar el paralelismo de grano grueso y fino

Portabilidad:
La API se especifica para C / C ++ y Fortran
Foro público para API y membresía
La mayoría de las principales plataformas se han implementado, incluidas las plataformas Unix / Linux y Windows

Historia:

A principios de los 90, los vendedores de máquinas de memoria compartida suministraron extensiones de programación
Fortran similares, basadas en directivas:
El usuario aumentaría un programa Fortran en serie con directivas que especificaban qué bucles debían paralelizarse
El compilador sería responsable de paralelizar automáticamente dichos bucles en los procesadores SMP.

Las implementaciones fueron todas funcionalmente similares, pero fueron divergentes (como de costumbre)

El i i t t tá d
https://computing.llnl.gov/tutorials/openMP/
f lb d d ANSI X3H5 1994 N f d t d t d bid l i t é2/55
26/6/2018 OpenMP
El primer intento en un estándar fue el borrador de ANSI X3H5 en 1994. Nunca fue adoptado, en gran parte debido al interés
cada vez menor a medida que las máquinas de memoria distribuida se hicieron populares.
Sin embargo, no mucho después de esto, comenzaron a prevalecer arquitecturas de máquinas de memoria compartida más
nuevas y se reanudó el interés.

La especificación estándar de OpenMP comenzó en la primavera de 1997, asumiendo el lugar donde se había dejado ANSI
X3H5.

Dirigido por OpenMP Architecture Review Board (ARB). Los miembros y colaboradores originales de ARB se muestran a
continuación. (Descargo de responsabilidad: todos los nombres de socios derivados del sitio web de OpenMP )

Miembros de APR Apoyando a los desarrolladores de Apoyando vendedores


aplicaciones de software
Compaq / Digital ADINA R & D, Inc. Absoft Corporation
Compañía Hewlett-Packard ANSYS, Inc. Editores portátiles de
Corporación Intel Dash Associates Edimburgo
International Business Machines Fluent, Inc. GENIAS Software
(IBM) División ILOG CPLEX GmBH
Kuck & Associates, Inc. (KAI) Livermore Software Technology Myrias Computer
Silicon Graphics, Inc. Corporation (LSTC) Technologies, Inc.
Sun Microsystems, Inc. MECALOG SARL The Portland Group,
Programa ASCI del Departamento Oxford Molecular Group PLC Inc. (PGI)
de Energía de EE. UU. The Numerical Algorithms
Group Ltd. (NAG)

Historial de versiones

OpenMP continúa evolucionando, se agregan nuevas construcciones y características con cada versión.

Inicialmente, las especificaciones API se publicaron por separado para C y Fortran. Desde 2005, han sido lanzados juntos.

La siguiente tabla muestra el historial de versiones de la API OpenMP.

Fecha Versión
Oct 1997 Fortran 1.0
Oct 1998 C / C ++ 1.0
Nov 1999 Fortran 1.1
Nov 2000 Fortran 2.0
Mar 2002 C / C ++ 2.0
Mayo 2005 OpenMP 2.5
Mayo 2008 OpenMP 3.0
Jul 2011 OpenMP 3.1
Jul 2013 OpenMP 4.0
Nov 2015 OpenMP 4.5

Este tutorial se refiere a OpenMP versión 3.1. La sintaxis y las funciones de las versiones más nuevas no están
cubiertas actualmente.

Referencias

Sitio web de OpenMP: especificaciones de OpenMP.org


API, preguntas frecuentes, presentaciones, debates, comunicados de prensa, calendario, solicitud de membresía y más ...

Wikipedia: en.wikipedia.org/wiki/OpenMP

Modelo de programación OpenMP

Modelo de memoria compartida:

OpenMP está diseñado para multiprocesador / núcleo, máquinas de memoria compartida. La arquitectura subyacente puede
ser memoria compartida UMA o NUMA.

https://computing.llnl.gov/tutorials/openMP/ 3/55
26/6/2018 OpenMP

Acceso a memoria uniforme Acceso a memoria no uniforme

Paralelismo basado en hilos:

Los programas OpenMP logran el paralelismo exclusivamente a través del uso de hilos.
Un hilo de ejecución es la unidad más pequeña de procesamiento que puede programar un sistema operativo. La idea de
una subrutina que se puede programar para ejecutarse de forma autónoma podría ayudar a explicar qué es un hilo.
Los hilos existen dentro de los recursos de un solo proceso. Sin el proceso, dejan de existir.
Normalmente, la cantidad de subprocesos coincide con la cantidad de procesadores / núcleos de la máquina. Sin embargo,
el uso real de los hilos depende de la aplicación.

Paralelismo explícito:

OpenMP es un modelo de programación explícito (no automático) que ofrece al programador un control total sobre la
paralelización.
La paralelización puede ser tan simple como tomar un programa en serie e insertar directivas de compilación ...
O tan complejo como insertar subrutinas para establecer múltiples niveles de paralelismo, bloqueos e incluso bloqueos
anidados.

Horquilla - Unir modelo:

OpenMP utiliza el modelo fork-join de ejecución paralela:

Todos los programas OpenMP comienzan como un proceso único: el hilo maestro . La secuencia maestra se ejecuta
secuencialmente hasta que se encuentra la primera construcción de región paralela .

HORQUILLA: el hilo maestro crea un equipo de hilos paralelos .

Las declaraciones en el programa que están encerradas por la construcción de la región paralela se ejecutan luego en
paralelo entre los diversos hilos del equipo.

UNIRSE: cuando los hilos del equipo completan las instrucciones en la construcción de la región paralela, se sincronizan y
terminan, dejando solo el hilo maestro.

El número de regiones paralelas y los hilos que las componen son arbitrarias.

Directiva del compilador basada:

La mayoría de los paralelos de OpenMP se especifican a través del uso de directivas de compilación que están incrustadas
en C / C ++ o el código fuente Fortran.
https://computing.llnl.gov/tutorials/openMP/ 4/55
26/6/2018 OpenMP

Paralelismo anidado:

La API proporciona la ubicación de regiones paralelas dentro de otras regiones paralelas.

Las implementaciones pueden o no admitir esta característica.

Hilos dinámicos:

La API proporciona el entorno de tiempo de ejecución para modificar dinámicamente la cantidad de subprocesos utilizados
para ejecutar regiones paralelas. Con la intención de promover un uso más eficiente de los recursos, si es posible.

Las implementaciones pueden o no admitir esta característica.

E / S:

OpenMP no especifica nada sobre E / S paralelas. Esto es particularmente importante si varios hilos intentan escribir / leer
desde el mismo archivo.

Si cada hilo conduce E / S a un archivo diferente, los problemas no son tan significativos.

Depende totalmente del programador asegurarse de que la E / S se realice correctamente dentro del contexto de un
programa de subprocesos múltiples.

Modelo de memoria: FLUSH ¿A menudo?

OpenMP proporciona una vista de "consistencia relajada" y "temporal" de la memoria de subprocesos (en sus palabras). En
otras palabras, los hilos pueden "almacenar en caché" sus datos y no están obligados a mantener una coherencia exacta
con la memoria real todo el tiempo.

Cuando es crítico que todos los hilos vean una variable compartida de manera idéntica, el programador es responsable de
asegurar que la variable sea FLUSHed por todos los hilos, según sea necesario.

Más sobre esto más tarde ...

Descripción general de la API OpenMP

Tres componentes:

La API de OpenMP 3.1 se compone de tres componentes distintos:


Directivas de compilación (19)
Rutinas de la biblioteca en tiempo de ejecución (32)
Variables de entorno (9)

Las API posteriores incluyen los mismos tres componentes, pero aumentan el número de directivas, rutinas de biblioteca de
tiempo de ejecución y variables de entorno.

El desarrollador de la aplicación decide cómo emplear estos componentes. En el caso más simple, solo se necesitan unos
pocos.

Las implementaciones difieren en su compatibilidad con todos los componentes API. Por ejemplo, una implementación
puede indicar que es compatible con el paralelismo anidado, pero la API deja en claro que puede estar limitado a un único
hilo: el hilo maestro. ¿No es exactamente lo que el desarrollador podría esperar?

Directrices del compilador:

Las directivas del compilador aparecen como comentarios en su código fuente y los compiladores las ignoran a menos que
usted les indique lo contrario, generalmente especificando el indicador del compilador apropiado, como se discutió en la
sección Compilación más adelante.

Las directivas de compilador OpenMP se utilizan para diversos fines:


Engendrando una región paralela
División de bloques de código entre hilos
Distribuir iteraciones de bucle entre hilos
Serializar secciones de código
Sincronización de trabajo entre hilos

Las directivas de compilación tienen la siguiente sintaxis:

https://computing.llnl.gov/tutorials/openMP/ 5/55
26/6/2018 OpenMP

Sentinel directive-name [cláusula, ...]


Por ejemplo:

Fortran ! $ OMP PREDETERMINADO PARALELO (COMPARTIDO) PRIVADO (BETA, PI)


C / C ++ #pragma omp paralelo predeterminado (compartido) privado (beta, pi)

Las directivas del compilador están cubiertas en detalle más adelante.

Rutinas de biblioteca en tiempo de ejecución:

La API OpenMP incluye un número cada vez mayor de rutinas de biblioteca en tiempo de ejecución.

Estas rutinas se usan para una variedad de propósitos:


Configuración y consulta del número de subprocesos
Consultar el identificador único de un subproceso (ID de subproceso), el identificador de ancestro de un subproceso, el
tamaño del equipo de subproceso
Configuración y consulta de la función de subprocesos dinámicos
Consultando si en una región paralela, y en qué nivel
Establecer y consultar el paralelismo anidado
Configuración, inicialización y terminación de bloqueos y bloqueos anidados
Consultar el tiempo y la resolución del reloj de pared

Para C / C ++, todas las rutinas de la biblioteca en tiempo de ejecución son subrutinas reales. Para Fortran, algunas son en
realidad funciones, y algunas son subrutinas. Por ejemplo:

Fortran FUNCIÓN INTEGER OMP_GET_NUM_THREADS ()


C / C ++ #include <omp.h>
int omp_get_num_threads (void)

Tenga en cuenta que para C / C ++, generalmente necesita incluir el archivo de encabezado <omp.h> .

Las rutinas de Fortran no distinguen entre mayúsculas y minúsculas, pero sí las rutinas de C / C ++.

Las rutinas de biblioteca en tiempo de ejecución se discuten brevemente como una visión general en el tiempo de ejecución
de rutinas de biblioteca sección, y con más detalle en el Apéndice A .

Variables de entorno:

OpenMP proporciona varias variables de entorno para controlar la ejecución de código paralelo en tiempo de ejecución.

Estas variables de entorno se pueden usar para controlar cosas tales como:
Establecer el número de hilos
Especificar cómo se dividen las interacciones de bucle
Enlazando hilos a procesadores
Habilitar / deshabilitar el paralelismo anidado; establecer los niveles máximos de paralelismo anidado
Habilitar / deshabilitar hilos dinámicos
Configurar el tamaño de la pila
Configuración de la política de espera del hilo

La configuración de las variables de entorno de OpenMP se realiza de la misma forma que configura cualquier otra variable
de entorno, y depende de qué shell usar. Por ejemplo:

csh / tcsh setenv OMP_NUM_THREADS 8


sh / bash exportar OMP_NUM_THREADS = 8

Las variables de entorno OpenMP se tratan en la sección Variables del entorno más adelante.

Ejemplo de estructura de código OpenMP:

Fortran - Estructura general del código

1 PROGRAMA HOLA
2
3 INTEGER VAR1 VAR2 VAR3
https://computing.llnl.gov/tutorials/openMP/ 6/55
26/6/2018 OpenMP
3 INTEGER VAR1, VAR2, VAR3
4
5 Código de serie
6 .
7 .
8 .
9
10 Principio de la región paralela. Tenedor un equipo de hilos.
11 Especificar el alcance de variable
12
13 ! $ OMP PARALELO PRIVADO (VAR1, VAR2) COMPARTIDO (VAR3)
14
15 Región paralela ejecutada por todos los hilos
16 .
17 Otras directivas OpenMP
18 .
19 Llamadas a la biblioteca en tiempo de ejecución
20 .
21 Todos los hilos se unen al hilo principal y se disuelven
22
23 ! $ OMP FINAL PARALELO
24
25 Reanudar el código de serie
26 .
27 .
28 .
29
30 FIN

C / C ++ - Estructura general del código

1 #include <omp.h>
2
3 principal () {
4
5 int var1, var2, var3;
6
7 Código de serie
8 .
9 .
10 .
11
12 Principio de la región paralela. Tenedor un equipo de hilos.
13 Especificar el alcance de variable
14
15 #pragma omp parallel private (var1, var2) shared (var3)
16 {
17
18 Región paralela ejecutada por todos los hilos
19 .
20 Otras directivas OpenMP
21 .
22 Llamadas a la biblioteca en tiempo de ejecución
23 .
24 Todos los hilos se unen al hilo principal y se disuelven
25
26 }
27
28 Reanudar el código de serie
29 .
30 .
31 .
32
https://computing.llnl.gov/tutorials/openMP/ 7/55
26/6/2018 OpenMP

33 }

Compilación de programas OpenMP

Implementaciones LC OpenMP:

A partir de junio de 2018, las fuentes de documentación para los compiladores por defecto de LC reclaman el siguiente
soporte OpenMP:

Plataforma Compilador Apoyos


Bandera de Versión
versión predeterminada
Linux Intel C / C ++, --versión 16.0.3 (TOSS 2) OpenMP 4.0
Fortran 18.0.1 (TOSS 3) OpenMP 4.5 (más)
GNU C / C ++, --versión 4.4.7 (TOSS 2) OpenMP 3.0
Fortran 4.9.3 (TOSS 3) OpenMP 4.0
PGI C / C ++, -V 8.0.1 (TOSS 2) OpenMP 3.0
Fortran --version 18.1 (TOSS 3) OpenMP 4.5 (limitaciones - sin
descarga de GPU)
Clang C / C ++ --versión 3.7.0 (TOSS 2) OpenMP 3.1
4.0.0 (TOSS 3) Algunos OpenMP 4.0 y 4.5
BG / Q IBM XL C / C ++ -version 12.1 OpenMP 3.1
IBM XL Fortran -version 14.1 OpenMP 3.1
GNU C / C ++, --versión 4.4.7 OpenMP 3.0
Fortran
SIERRA IBM XL C / C ++ -version 16.01 beta OpenMP 4.5
CORAL
IBM XL Fortran -version 16.01 beta OpenMP 4.5
EA
GNU C / C ++ --versión 4.9.3 OpenMP 4.0
GNU Fortran --versión 4.9.3 OpenMP 4.0
PGI C / C ++, -V 18.5-0 OpenMP 4.5 (limitaciones - sin
Fortran --version descarga de GPU)
Clang C / C ++ --versión 4.0 beta OpenMP 4.5
(IBM)

Para ver todas las versiones del compilador LC, use los comandos:

TOSS 2, BG / Q: use -l compiladores


TOSS 3, CORAL EA: módulo disponible

El mejor lugar para ver el soporte de OpenMP por una variedad de compiladores:
https://www.openmp.org/resources/openmp-compilers-tools/ .

Compilando:

Todos los compiladores de LC requieren que utilice el indicador de compilación apropiado para "activar" las compilaciones de
OpenMP. La tabla a continuación muestra qué usar para cada compilador.

Para los comandos del compilador de MPI, consulte: https://computing.llnl.gov/tutorials/mpi/#BuildScripts

Compilador / plataforma Comandos del compilador Bandera de OpenMP


Intel icc -qopenmp
Linux icpc
ifort
GNU gcc -fopenmp
Linux g ++
IBM Blue Gene g77
https://computing.llnl.gov/tutorials/openMP/ 8/55
26/6/2018 OpenMP
IBM Blue Gene g77
Sierra, CORAL EA gfortran
PGI pgcc -mp
Linux pgCC
Sierra, CORAL EA pgf77
pgf90
Clang clang -fopenmp
Linux clang ++
Sierra, CORAL EA
IBM XL bgxlc_r, bgcc_r -qsmp = omp
Blue Gene bgxlC_r, bgxlc ++ _ r
bgxlc89_r
bgxlc99_r
bgxlf_r
bgxlf90_r
bgxlf95_r
bgxlf2003_r
IBM XL xlc_r -qsmp = omp
Sierra, CORAL EA xlC_r, xlc ++ _ r
xlf_r
xlf90_r
xlf95_r
xlf2003_r
xlf2008_r

Documentación del compilador:


Intel y PGI: los documentos del compilador se incluyen en el directorio / opt / compilername . De lo contrario,
consulte las páginas web Intel o PGI.
GNU: gnu.org
Clang: http://clang.llvm.org/docs/
IBM BlueGene: www-01.ibm.com/software/awdtools/fortran/ y www-01.ibm.com/software/awdtools/xlcpp
IBM Sierra, CORAL EA: seleccione la versión relevante de los documentos de Little Endian en http://www-
01.ibm.com/support/docview.wss?uid=swg27036675 (C / C ++) y http: // www-01. ibm.com/support/docview.wss?
uid=swg27036672 (Fortran).

Directivas OpenMP

Formato de directivas Fortran


Formato: (sin distinción de mayúsculas y minúsculas)

centinela nombre-directiva [cláusula ...]


Todas las directivas de Fortran OpenMP Una directiva OpenMP Opcional. Las cláusulas pueden
deben comenzar con un centinela. Los válida. Debe aparecer estar en cualquier orden y
centinelas aceptados dependen del tipo de después del centinela y repetirse según sea necesario a
fuente de Fortran. Los posibles centinelas antes de cualquier menos que se restrinja de otra
son: cláusula. manera.

! $ OMP
C $ OMP
* $ OMP

Ejemplo:

! $ OMP PREDETERMINADO PARALELO (COMPARTIDO) PRIVADO (BETA, PI)

Fuente de forma fija:

! $ OMP C $ OMP * $ OMP son aceptados como centinelas y deben comenzar en la columna 1

T d l l d f l i fij d F t l l d l it d d lí i bl ti ió
https://computing.llnl.gov/tutorials/openMP/ 9/55
26/6/2018 OpenMP
Todas las reglas de formulario fijo de Fortran para las columnas de longitud de línea, espacio en blanco, continuación y
comentario se aplican a toda la línea directiva.
Las líneas de directiva inicial deben tener un espacio / cero en la columna 6.

Las líneas de continuación deben tener un espacio no cero en la columna 6.

Fuente de forma gratuita:

! $ OMP es el único centinela aceptado. Puede aparecer en cualquier columna, pero debe estar precedido solo por espacios
en blanco.

Todas las reglas de forma libre de Fortran para las columnas de longitud de línea, espacio en blanco, continuación y
comentario se aplican a toda la línea directiva.

Las líneas de directiva iniciales deben tener un espacio después del centinela.

Las líneas de continuación deben tener un ampersand como el último carácter que no está en blanco en una línea. La
siguiente línea debe comenzar con un centinela y luego con las directivas de continuación.

Reglas generales:

Los comentarios no pueden aparecer en la misma línea que una directiva

Solo se puede especificar un nombre de directiva por directiva

Los compiladores Fortran que están habilitados para OpenMP generalmente incluyen una opción de línea de comando que
instruye al compilador a activar e interpretar todas las directivas OpenMP.

Varias directivas de Fortran OpenMP vienen en pares y tienen el formulario que se muestra a continuación. La directiva
"final" es opcional, pero se recomienda su legibilidad.

Directiva
$ OMP

[bloque de código estructurado]

! $ OMP directiva final

Directivas OpenMP

Formato de directivas C / C ++
Formato:

#pragma omp nombre-directiva [cláusula, ...] nueva línea


Requerido Una directiva OpenMP Opcional. Las cláusulas pueden estar Necesario. Precede al
para todas las válida. Debe aparecer en cualquier orden y repetirse según bloque estructurado
directivas después del pragma y sea necesario a menos que se que está encerrado por
OpenMP C / C antes de cualquier cláusula. restrinja de otra manera. esta directiva.
++.

Ejemplo:

#pragma omp paralelo predeterminado (compartido) privado (beta, pi)

Reglas generales:

Distingue mayúsculas y minúsculas

Las directivas siguen las convenciones de los estándares C / C ++ para directivas de compilación

Solo se puede especificar un nombre de directiva por directiva


https://computing.llnl.gov/tutorials/openMP/ 10/55
26/6/2018 OpenMP

Cada directiva se aplica como máximo a una declaración siguiente, que debe ser un bloque estructurado.
Las líneas directivas largas se pueden "continuar" en líneas sucesivas escapando del carácter de nueva línea con una barra
diagonal inversa ("\") al final de una línea directiva.

Directivas OpenMP

Alcance Directivo
¿Hacemos esto ahora ... o lo hacemos más tarde? Oh, bueno, terminemos pronto ...

Estático (Léxico) Extensión:

El código encerrado textualmente entre el principio y el final de un bloque estructurado siguiendo una directiva.

La extensión estática de una directiva no abarca múltiples rutinas o archivos de código

Directiva huérfana:

Se dice que una directiva OpenMP que aparece independientemente de otra directiva adjunta es una directiva huérfana.
Existe fuera de la extensión estática (léxica) de otra directiva.

Extenderá las rutinas y posiblemente los archivos de códigos

Extensión dinámica:

El alcance dinámico de una directiva incluye tanto su alcance estático (léxico) como la extensión de sus directivas huérfanas.

Ejemplo:

PRUEBA DEL PROGRAMA SUBROUTINA SUB1


... ...
! $ OMP PARALELO ! $ OMP CRÍTICA
... ...
! $ OMP DO ! $ OMP END CRITICAL
DO I = ... FIN
...
CALL SUB1
... SUBROUTINA SUB2
ENDDO ...
! $ OMP END DO ! SECCIONES $ OMP
... ...
LLAMAR SUB2 ! $ OMP SECCIONES FINALES
... ...
! $ OMP FINAL PARALELO FIN
EXTENSIÓN ESTÁTICA DIRECTIVAS HUÉRFANAS
La directiva DO se produce dentro de una región Las directivas CRÍTICAS y SECCIONES ocurren fuera
paralela envolvente de una región paralela que lo encierra
LA EXTENSIÓN DINÁMICA
Las directivas CRÍTICAS y SECCIONES se producen dentro del alcance dinámico de las directivas DO y
PARALLEL.

¿Porque es esto importante?

OpenMP especifica una serie de reglas de alcance sobre cómo las directivas pueden asociar (vincular) y anidar entre sí

Pueden producirse programas ilegales y / o incorrectos si se ignoran las reglas de enlace y anidamiento de OpenMP.

Consulte las Reglas de vinculación y anidación de directivas para obtener detalles específicos

Directivas OpenMP

Construcción de la región PARALELA


https://computing.llnl.gov/tutorials/openMP/ 11/55
26/6/2018 OpenMP
Construcción de la región PARALELA

Propósito:

Una región paralela es un bloque de código que será ejecutado por múltiples hilos. Esta es la construcción paralela de
OpenMP.

Formato:

! $ OMP PARALLEL [cláusula ...]


IF (scalar_logical_expression)
PRIVATE (list)
SHARED (lista)
PREDETERMINADO (PRIVADO | FIRSTPRIVATE | COMPARTIDO | NINGUNO)
FIRSTPRIVATE (list)
REDUCTION (operador: list)
Fortran COPYIN (list)
NUM_THREADS (expresión-entero-escalar)

bloquear

! $ OMP FINAL PARALELO

#pragma omp parallel [cláusula ...] newline


if (scalar_expression)
private (lista)
shared (lista)
predeterminado (compartido | ninguno)
firstprivate (list)
C/C reduction (operador: list)
++
copyin (list)
num_threads (integer-expression)

structure_block

Notas:

Cuando un hilo alcanza una directiva PARALELA, crea un equipo de hilos y se convierte en el maestro del equipo. El maestro
es miembro de ese equipo y tiene el número de hilo 0 dentro de ese equipo.

Comenzando desde el comienzo de esta región paralela, el código se duplica y todos los hilos ejecutarán ese código.

Hay una barrera implícita al final de una región paralela. Solo el hilo maestro continúa la ejecución más allá de este punto.

Si un hilo termina en una región paralela, todos los hilos del equipo finalizarán y el trabajo realizado hasta ese momento no
estará definido.

¿Cuántos hilos?

El número de subprocesos en una región paralela está determinado por los siguientes factores, en orden de precedencia:

1. Evaluación de la cláusula IF

2. Configuración de la cláusula NUM_THREADS

3. Uso de la función de biblioteca omp_set_num_threads ()

4. Configuración de la variable de entorno OMP_NUM_THREADS

5. Valor predeterminado de implementación: por lo general, el número de CPU en un nodo, aunque podría ser dinámico
(consulte el siguiente punto).

Los hilos están numerados de 0 (hilo maestro) a N-1

Hilos dinámicos:

Utilice la función de biblioteca omp_get_dynamic () para determinar si los subprocesos dinámicos están habilitados.

https://computing.llnl.gov/tutorials/openMP/ 12/55
26/6/2018 OpenMP

Si es compatible, los dos métodos disponibles para habilitar los hilos dinámicos son:

1. La rutina de la biblioteca omp_set_dynamic ()

2. Configuración de la variable de entorno OMP_DYNAMIC en TRUE

Regiones paralelas anidadas:

Utilice la función de biblioteca omp_get_nested () para determinar si las regiones paralelas anidadas están habilitadas.

Los dos métodos disponibles para habilitar regiones paralelas anidadas (si se admiten) son:

1. La rutina de la biblioteca omp_set_nested ()

2. Configuración de la variable de entorno OMP_NESTED en TRUE

Si no se admite, una región paralela anidada dentro de otra región paralela da como resultado la creación de un nuevo
equipo, que consiste en un hilo, por defecto.

Cláusulas:

Cláusula IF : si está presente, debe evaluar a .TRUE. (Fortran) o distinto de cero (C / C ++) para que se cree un equipo de
subprocesos. De lo contrario, la región se ejecuta en serie mediante el hilo maestro.

Las cláusulas restantes se describen en detalle más adelante, en la sección Cláusulas de atributos del alcance de los datos .

Restricciones

Una región paralela debe ser un bloque estructurado que no abarca múltiples rutinas o archivos de código

Es ilegal ramificar (entrar) dentro o fuera de una región paralela

Solo se permite una sola cláusula IF

Solo se permite una sola cláusula NUM_THREADS

Un programa no debe depender del orden de las cláusulas

Ejemplo: Región Paralela

Programa simple "Hello World"


Cada hilo ejecuta todo el código encerrado en la región paralela
Las rutinas de la biblioteca OpenMP se utilizan para obtener identificadores de subprocesos y el número total de
subprocesos

Fortran - Ejemplo de región paralela

1 PROGRAMA HOLA
2
3 INTEGER NTHREADS, TID, OMP_GET_NUM_THREADS ,
4 + OMP_GET_THREAD_NUM
5
6 ! ¡Tenedor de un equipo de hilos con cada hilo que tiene una variable TID privada
7 ! $ OMP PARALELO PRIVADO (TID)
8
9 ! Obtenga e imprima la id del hilo
10 TID = OMP_GET_THREAD_NUM ()
11 IMPRIMIR *, 'Hello World from thread =', TID
12
13 ! Solo el hilo maestro hace esto
14 IF (TID .EQ. 0) ENTONCES
15 NTHREADS = OMP_GET_NUM_THREADS ()
16 PRINT *, 'Número de hilos =', NTHREADS
17 TERMINARA SI
18
19 ! ¡Todos los hilos se unen al hilo maestro y se disuelven
20 ! $ OMP END PARALLEL
21
https://computing.llnl.gov/tutorials/openMP/ 13/55
26/6/2018 OpenMP
21
22
FIN

C / C ++ - Ejemplo de región paralela

1 #include <omp.h>
2
3 main (int argc, char * argv []) {
4
5 int nthreads, tiempo;
6
7 / * Tenedor de un equipo de hilos con cada hilo que tiene una variable tid privada * /
8 #pragma omp paralelo privado (tid)
9 {
10
11 / * Obtenga e imprima la id del hilo * /
12 tid = omp_get_thread_num () ;
13 printf ("Hola mundo desde el hilo =% d \ n", tid);
14
15 / * Solo el hilo maestro hace esto * /
16 if (tiempo == 0)
17 {
18 nthreads = omp_get_num_threads () ;
19 printf ("Número de hilos =% d \ n", n hilos);
20 }
21
22 } / * Todos los hilos unen el hilo maestro y terminan * /
23
24 }

Ejercicio 1 de OpenMP

Empezando

Visión de conjunto:

Inicie sesión en el grupo de talleres con el nombre de usuario de su taller y el token OTP
Copie los archivos de ejercicios a su directorio de inicio
Familiarizarse con el entorno OpenMP de LC
Escriba un simple programa "Hello World" OpenMP
Compila con éxito tu programa
Ejecute con éxito su programa
Modificar la cantidad de hilos utilizados para ejecutar su programa

IR AL EJERCICIO AQUÍ

Aprox. 20 minutos

https://computing.llnl.gov/tutorials/openMP/ 14/55
26/6/2018 OpenMP

Directivas OpenMP

Construcciones de trabajo compartido

Una construcción de trabajo compartido divide la ejecución de la región de código adjunta entre los miembros del equipo que
la encuentra.

Las construcciones de trabajo compartido no lanzan nuevos hilos

No existe una barrera implícita al ingresar a una construcción de trabajo compartido, sin embargo, hay una barrera implícita
al final de una construcción de trabajo compartido.

Tipos de construcciones de trabajo compartido:

NOTA: La construcción de trabajo compartido Fortran no se muestra aquí.

DO / for - comparte iteraciones de un SECCIONES : divide el trabajo en SINGLE - serializa una sección de
bucle en el equipo. Representa un tipo secciones separadas y discretas. Cada código
de "paralelismo de datos". sección se ejecuta mediante un hilo. Se
puede usar para implementar un tipo de
"paralelismo funcional".

Restricciones

Una construcción de trabajo compartido debe estar encerrada dinámicamente dentro de una región paralela para que la
directiva se ejecute en paralelo.

Los constructos de trabajo compartido deben ser encontrados por todos los miembros de un equipo o ninguno en absoluto

Las construcciones sucesivas de trabajo compartido deben ser encontradas en el mismo orden por todos los miembros de un
equipo

Directivas OpenMP

Construcciones de trabajo compartido


DO / para directiva
Propósito:

La directiva DO / for especifica que el equipo debe ejecutar paralelamente las iteraciones del ciclo inmediatamente posterior.
Esto supone que ya se ha iniciado una región paralela; de lo contrario, se ejecuta en serie en un solo procesador.
https://computing.llnl.gov/tutorials/openMP/ 15/55
26/6/2018 OpenMP

Formato:

! $ OMP DO [cláusula ...]


HORARIO (tipo [, fragmento])
ORDENADO
PRIVADO (lista)
FIRSTPRIVATE (lista)
LASTPRIVATE (lista)
COMPARTIDA (lista)
Fortran REDUCCIÓN (operador: lista)
COLAPSO (n)

do_loop

! $ OMP END DO [NOWAIT]

#pragma omp para [cláusula ...]


calendario de nueva línea (tipo [, fragmento])
ordenado
privado (lista)
primerprivado (lista)
últimoprivado (lista)
C/C compartido (lista)
++
reducción (operador: lista)
colapso (n)
no, espera

en bucle

Cláusulas:

PROGRAMA : Describe cómo las iteraciones del ciclo se dividen entre los hilos del equipo. El cronograma predeterminado
depende de la implementación. Para una discusión sobre cómo un tipo de programación puede ser más óptima que otras,
vea http://openmp.org/forum/viewtopic.php?f=3&t=83 .

ESTÁTICO
Iteraciones del bucle se dividen en piezas de tamaño de trozo y luego asignados estáticamente a las roscas. Si no se
especifica el fragmento, las iteraciones se dividen uniformemente (si es posible) de forma contigua entre los hilos.

DINÁMICA
Iteraciones del bucle se dividen en piezas de tamaño de trozo , y dinámicamente programadas entre los hilos; cuando
un hilo termina un trozo, dinámicamente se le asigna otro. El tamaño de fragmento predeterminado es 1.

GUIADO
Las iteraciones se asignan dinámicamente a los hilos en bloques a medida que los hilos los solicitan hasta que no
quedan bloques por asignar. Similar a DYNAMIC excepto que el tamaño del bloque disminuye cada vez que se le da un
paquete de trabajo a un hilo. El tamaño del bloque inicial es proporcional a:

number_of_iterations / number_of_threads

Los bloques posteriores son proporcionales a

number_of_iterations_remaining / number_of_threads

El parámetro de fragmento define el tamaño de bloque mínimo. El tamaño de fragmento predeterminado es 1.

DURACIÓN
La variable de entorno OMP_SCHEDULE difiere la decisión de programación hasta el tiempo de ejecución. Es ilegal
especificar un tamaño de fragmento para esta cláusula.

AUTO
La decisión de programación se delega al compilador y / o al sistema de tiempo de ejecución.

NO WAIT / nowait : si se especifica, los hilos no se sincronizan al final del ciclo paralelo.

ORDERED : especifica que las iteraciones del ciclo deben ejecutarse como lo harían en un programa en serie.

COLAPSO : especifica cuántos bucles de un bucle anidado deben colapsarse en un espacio grande de iteración y dividirse
según la cláusula de programación La ejecución secuencial de las iteraciones en todos los bucles asociados determina el
https://computing.llnl.gov/tutorials/openMP/ 16/55
26/6/2018 OpenMP
según la cláusula de programación . La ejecución secuencial de las iteraciones en todos los bucles asociados determina el
orden de las iteraciones en el espacio de iteración contraído.
Otras cláusulas se describen en detalle más adelante en la sección Cláusulas de atributos del alcance de los datos .

Restricciones

El bucle DO no puede ser un bucle DO WHILE o un bucle sin control de bucle. Además, la variable de iteración de bucle
debe ser un número entero y los parámetros de control de bucle deben ser los mismos para todos los hilos.

La corrección del programa no debe depender de qué hilo ejecuta una iteración particular.

Es ilegal realizar una bifurcación (salida) de un bucle asociado con una directiva DO / for.

El tamaño del fragmento debe especificarse como un bucle en una expresión entera invariable, ya que no hay sincronización
durante su evaluación por diferentes subprocesos.

Las cláusulas ORDERED, COLLAPSE y SCHEDULE pueden aparecer una vez cada una.

Consulte el documento de la especificación OpenMP para conocer las restricciones adicionales.

Ejemplo: DO / para Directiva

Programa simple vector-add


Las matrices A, B, C y la variable N serán compartidas por todos los hilos.
Variable Seré privado para cada hilo; cada hilo tendrá su propia copia única.
Las iteraciones del bucle se distribuirán dinámicamente en piezas de tamaño CHUNK.
Los hilos no se sincronizarán al completar sus piezas individuales de trabajo (NOWAIT).

Ejemplo de Directiva Fortran - DO

1 PROGRAMA VEC_ADD_DO
2
3 INTEGER N, CHUNKSIZE, CHUNK, I
4 PARÁMETRO (N = 1000)
5 PARÁMETRO (CHUNKSIZE = 100)
6 REAL A (N), B (N), C (N)
7
8 ! Algunas inicializaciones
9 DO I = 1, N
10 A (I) = I * 1.0
11 B (I) = A (I)
12 ENDDO
13 CHUNK = CHUNKSIZE
14
15 ! $ OMP PARALELO COMPARTIDO (A, B, C, CHUNK) PRIVADO (I)
16
17 ! $ OMP DO SCHEDULE (DINÁMICO, CHUNK)
18 DO I = 1, N
19 C (I) = A (I) + B (I)
20 ENDDO
21 ! $ OMP END DO NOWAIT
22
23 ! $ OMP FINAL PARALELO
24
25 FIN

C / C ++ - para el ejemplo de directiva

1 #include <omp.h>
https://computing.llnl.gov/tutorials/openMP/ 17/55
26/6/2018 OpenMP
# c ude o p.
2 #define N 1000

3 #define CHUNKSIZE 100


4
5 main (int argc, char * argv []) {
6
7 int i, pedazo;
8 flotar a [N], b [N], c [N];
9
10 / * Algunas inicializaciones * /
11 para (i = 0; i <N; i ++)
12 a [i] = b [i] = i * 1.0;
13 trozo = CHUNKSIZE;
14
15 #pragma omp parallel shared (a, b, c, chunk) privado (i)
16 {
17
18 #pragma omp para el horario (dinámico, fragmento) nowait
19 para (i = 0; i <N; i ++)
20 c [i] = a [i] + b [i];
21
22 } / * fin de la región paralela * /
23
24 }

Directivas OpenMP

Construcciones de trabajo compartido


SECCIONES Directiva
Propósito:

La directiva SECTIONS es una construcción no iterativa de trabajo compartido. Especifica que las secciones adjuntas de
código se dividen entre los hilos del equipo.

Las directivas SECTION independientes están anidadas dentro de una directiva SECTIONS. Cada SECCIÓN se ejecuta una
vez por un hilo en el equipo. Diferentes secciones pueden ser ejecutadas por diferentes hilos. Es posible que un subproceso
ejecute más de una sección si es lo suficientemente rápido y la implementación lo permite.

Formato:

! $ OMP SECTIONS [cláusula ...]


PRIVATE (list)
FIRSTPRIVATE (list)
LASTPRIVATE (list)
REDUCTION (operator | intrinsic: list)

! SECCIÓN $ OMP
Fortran
bloquear

! SECCIÓN $ OMP

bloquear

! $ OMP SECCIONES FINALES [NOWAIT]

C/C #pragma omp sections [cláusula ...] nueva línea


++ privada (lista)
firstprivate (lista)
lastprivate (lista)
reducción (operador: lista)
no, espera
{
https://computing.llnl.gov/tutorials/openMP/ 18/55
26/6/2018 OpenMP
{

#pragma omp section newline

structure_block

#pragma omp section newline

structure_block

Cláusulas:

Existe una barrera implícita al final de una directiva SECTIONS , a menos que se use la cláusula NOWAIT / nowait .

Las cláusulas se describen en detalle más adelante, en la sección Cláusulas de atributos del alcance de los datos .

Preguntas:

¿Qué sucede si la cantidad de hilos y el número de SECCIONES son diferentes? ¿Más hilos que SECCIONES?
¿Menos hilos que SECCIONES?
Responder

¿Qué hilo ejecuta qué SECCIÓN?


Responder

Restricciones

Es ilegal ramificar (entrar) dentro o fuera de bloques de sección.

Las directivas de SECTION deben ocurrir dentro del alcance léxico de una directiva SECTIONS adjunta (no SECCIONES
huérfanas).

Ejemplo: SECCIONES Directiva

Programa simple que demuestra que diferentes bloques de trabajo se realizarán por diferentes hilos.

Fortran - Ejemplo de Directiva de SECCIONES

1 PROGRAMA VEC_ADD_SECTIONS
2
3 INTEGER N, I
4 PARÁMETRO (N = 1000)
5 REAL A (N), B (N), C (N), D (N)
6
7 ! Algunas inicializaciones
8 DO I = 1, N
9 A (I) = I * 1.5
10 B (I) = I + 22.35
11 ENDDO
12
13 ! $ OMP PARALELO COMPARTIDO (A, B, C, D), PRIVADO (I)
14
15 ! SECCIONES $ OMP
16
17 ! SECCIÓN $ OMP
18 DO I = 1, N
19 C (I) = A (I) + B (I)
20 ENDDO
21
22 ! SECCIÓN $ OMP
23 DO I = 1, N
24 D (I) = A (I) * B (I)
25 ENDDO
https://computing.llnl.gov/tutorials/openMP/ 19/55
26/6/2018 OpenMP
5 O
26

27 ! $ OMP END SECTIONS NOWAIT


28
29 ! $ OMP FINAL PARALELO
30
31 FIN

C / C ++ - secciones Directiva Ejemplo

1 #include <omp.h>
2 #define N 1000
3
4 main (int argc, char * argv []) {
5
6 int i;
7 flotar a [N], b [N], c [N], d [N];
8
9 / * Algunas inicializaciones * /
10 para (i = 0; i <N; i ++) {
11 a [i] = i * 1.5;
12 b [i] = i + 22.35;
13 }
14
15 #pragma omp paralelo compartido (a, b, c, d) privado (i)
16 {
17
18 #pragma omp secciones nowait
19 {
20
21 #pragma omp section
22 para (i = 0; i <N; i ++)
23 c [i] = a [i] + b [i];
24
25 #pragma omp section
26 para (i = 0; i <N; i ++)
27 d [i] = a [i] * b [i];
28
29 } / * fin de las secciones * /
30
31 } / * fin de la región paralela * /
32
33 }

Directivas OpenMP

Construcciones de trabajo compartido SOLICITUD


ÚNICA
Propósito:

La directiva SINGLE especifica que el código adjunto debe ser ejecutado por un solo hilo en el equipo.

Puede ser útil cuando se trata de secciones de código que no son seguras para subprocesos (como E / S)

Formato:

F t ! $ OMP SINGLE [ lá l ]
https://computing.llnl.gov/tutorials/openMP/ 20/55
26/6/2018 OpenMP
Fortran ! $ OMP SINGLE [cláusula ...]
PRIVATE (list)
FIRSTPRIVATE (lista)

bloquear

! $ OMP END SINGLE [NOWAIT]

#pragma omp single [cláusula ...] nueva línea


privada (lista)
firstprivate (lista)
C/C no, espera
++
structure_block

Cláusulas:

Los hilos en el equipo que no ejecutan la directiva SINGLE, esperan al final del bloque de código adjunto, a menos que se
especifique una cláusula NOWAIT / nowait .

Las cláusulas se describen en detalle más adelante, en la sección Cláusulas de atributos del alcance de los datos .

Restricciones

Es ilegal ramificarse dentro o fuera de un bloque SIMPLE.

Directivas OpenMP

Construcciones combinadas de trabajo compartido en paralelo

OpenMP proporciona tres directivas que son simplemente conveniencias:


PARALELO / paralelo para
SECCIONES PARALELAS
TALLER PARALELO (solo para Fortran)

En su mayor parte, estas directivas se comportan de manera idéntica a una directiva PARALELO individual, seguida
inmediatamente por una directiva de trabajo por separado.

La mayoría de las reglas, cláusulas y restricciones que se aplican a ambas directivas están vigentes. Ver la API de OpenMP
para más detalles.

A continuación se muestra un ejemplo que utiliza el PARALELO DO / paralelo para la directiva combinada.

Fortran - PARALELO DO Directiva Ejemplo

1 PROGRAMA VECTOR_ADD
2
3 INTEGER N, I, CHUNKSIZE, CHUNK
4 PARÁMETRO (N = 1000)
5 PARÁMETRO (CHUNKSIZE = 100)
6 REAL A (N), B (N), C (N)
7
8 ! Algunas inicializaciones
9 DO I = 1, N
10 A (I) = I * 1.0
11 B (I) = A (I)
12 ENDDO
13 CHUNK = CHUNKSIZE
14
15 ! $ OMP PARALELO DO
16 ! $ OMP Y COMPARTIDO (A, B, C, CHUNK) PRIVADO (I)
17 ! $ OMP & SCHEDULE (ESTÁTICA CHUNK)
https://computing.llnl.gov/tutorials/openMP/ 21/55
26/6/2018 OpenMP
17 ! $ OMP & SCHEDULE (ESTÁTICA, CHUNK)
18
19 DO I = 1, N
20 C (I) = A (I) + B (I)
21 ENDDO
22
23 ! $ OMP END PARALELO DO
24
25 FIN

C / C ++ - paralelo para el ejemplo directivo

1 #include <omp.h>
2 #define N 1000
3 #define CHUNKSIZE 100
4
5 main (int argc, char * argv []) {
6
7 int i, pedazo;
8 flotar a [N], b [N], c [N];
9
10 / * Algunas inicializaciones * /
11 para (i = 0; i <N; i ++)
12 a [i] = b [i] = i * 1.0;
13 trozo = CHUNKSIZE;
14
15 #pragma omp parallel for \
16 compartido (a, b, c, chunk) privado (i) \
17 horario (estático, fragmento)
18 para (i = 0; i <N; i ++)
19 c [i] = a [i] + b [i];
20 }

Directivas OpenMP

TASK Construct
Propósito:

El constructo TASK define una tarea explícita, que puede ser ejecutada por el hilo que se encuentra, o diferida para su
ejecución por cualquier otro hilo en el equipo.

El entorno de datos de la tarea está determinado por las cláusulas de atributo de intercambio de datos.

La ejecución de tareas está sujeta a la programación de tareas; consulte el documento de especificaciones de OpenMP 3.1
para obtener más información.

Consulte también la documentación de OpenMP 3.1 para las directivas asociadas taskyield y taskwait .

Formato:

Fortran ! $ OMP TASK [cláusula ...]


IF (expresión lógica escalar)
FINAL (expresión lógica escalar)
DESATADO
PREDETERMINADO (PRIVADO | FIRSTPRIVATE | COMPARTIDO | NINGUNO)
MERGEABLE
PRIVADO (lista)
https://computing.llnl.gov/tutorials/openMP/ 22/55
26/6/2018 OpenMP
FIRSTPRIVATE (lista)
COMPARTIDO (lista)

bloquear

! $ OMP END TASK

#pragma omp task [cláusula ...] newline


if (expresión escalar)
final (expresión escalar)
desatado
predeterminado (compartido | ninguno)
C/C fusionable
++ privado (lista)
primerprivado (lista)
compartido (lista)

structure_block

Cláusulas y restricciones:

Consulte el documento de especificaciones de OpenMP 3.1 para más detalles.

Ejercicio 2 de OpenMP

Construcciones de trabajo compartido

Visión de conjunto:

Inicie sesión en el clúster de talleres LC, si aún no ha iniciado sesión


Work-Sharing DO / para construir ejemplos: revisar, compilar y ejecutar
Ejemplo de construcción de SECCIONES de trabajo compartido: revisar, compilar y ejecutar

IR AL EJERCICIO AQUÍ

Aprox. 20 minutos

Directivas OpenMP

Construcciones de sincronización
Considere un ejemplo simple donde dos hilos en dos procesadores diferentes intentan incrementar una variable x al mismo
tiempo (suponiendo que x es inicialmente 0):

HILO 1: HILO 2:

incremento (x) incremento (x)


{ {
x = x + 1; x = x + 1;
https://computing.llnl.gov/tutorials/openMP/ 23/55
26/6/2018 OpenMP
x = x + 1; x = x + 1;
} }

HILO 1: HILO 2:

10 CARGAR A, (x dirección) 10 CARGAR A, (x dirección)


20 ADD A, 1 20 ADD A, 1
30 TIENDA A, (x dirección) 30 TIENDA A, (x dirección)

Una posible secuencia de ejecución:


1. El subproceso 1 carga el valor de x en el registro A.
2. El subproceso 2 carga el valor de x en el registro A.
3. El subproceso 1 agrega 1 para registrar A
4. El hilo 2 agrega 1 para registrar A
5. El hilo 1 almacena el registro A en la ubicación x
6. El hilo 2 almacena el registro A en la ubicación x

El valor resultante de x será 1, no 2 como debería ser.

Para evitar una situación como esta, el incremento de x debe sincronizarse entre los dos hilos para garantizar que se
produzca el resultado correcto.

OpenMP proporciona una variedad de construcciones de sincronización que controlan cómo la ejecución de cada hilo
procede en relación con otros hilos del equipo.

Directivas OpenMP

Construcciones de sincronización
Directiva MASTER
Propósito:

La directiva MASTER especifica una región que se ejecutará solo por el hilo maestro del equipo. Todos los otros hilos en el
equipo saltan esta sección de código

No hay una barrera implícita asociada con esta directiva

Formato:

! $ OMP MASTER

bloquear
Fortran
! $ OMP END MASTER

#pragma omp master newline


C/C
++ structure_block

Restricciones

Es ilegal ramificarse dentro o fuera del bloque MASTER.

Directivas OpenMP

Construcciones de sincronización
Directiva CRÍTICA
Propósito:

La directiva CRITICAL especifica una región de código que debe ejecutarse solo por un hilo a la vez.

https://computing.llnl.gov/tutorials/openMP/ 24/55
26/6/2018 OpenMP

Formato:

! $ OMP CRITICAL [nombre]

bloquear
Fortran
! $ OMP END CRITICAL [nombre]

#pragma omp critical [name] newline


C/C
++ structure_block

Notas:

Si un hilo se está ejecutando actualmente dentro de una región CRÍTICA y otro hilo alcanza esa región CRÍTICA e intenta
ejecutarlo, bloqueará hasta que el primer hilo salga de esa región CRÍTICA.

El nombre opcional permite que existan múltiples regiones CRÍTICAS diferentes:


Los nombres actúan como identificadores globales. Diferentes regiones CRÍTICAS con el mismo nombre se tratan
como la misma región.
Todas las secciones CRÍTICAS sin nombre se tratan como la misma sección.

Restricciones

Es ilegal ramificarse dentro o fuera de un bloque CRÍTICO.

Fortran solamente: los nombres de constructos críticos son entidades globales del programa. Si un nombre entra en conflicto
con cualquier otra entidad, el comportamiento del programa no está especificado.

Ejemplo: Construcción CRÍTICA

Todos los hilos del equipo intentarán ejecutar en paralelo, sin embargo, debido a la construcción CRÍTICA que rodea el
incremento de x, solo un hilo podrá leer / incrementar / escribir x en cualquier momento

Fortran - Ejemplo de Directiva CRÍTICA

1 PROGRAMA CRÍTICO
2
3 INTEGER X
4 X = 0
5
6 ! $ OMP PARALLEL COMPARTIDO (X)
7
8 ! $ OMP CRÍTICA
9 X = X + 1
10 ! $ OMP END CRITICAL
11
12 ! $ OMP FINAL PARALELO
13
14 FIN

C / C ++ - Ejemplo de directiva crítica

1 #include <omp.h>
2
3 main (int argc, char * argv []) {
4
https://computing.llnl.gov/tutorials/openMP/ 25/55
26/6/2018 OpenMP
4
5 int x;
6 x = 0;
7
8 #pragma omp paralelo compartido (x)
9 {
10
11 #pragma omp critical
12 x = x + 1;
13
14 } / * fin de la región paralela * /
15
16 }

Directivas OpenMP

Construcciones de sincronización
Directiva BARRERA
Propósito:

La directiva BARRIER sincroniza todos los hilos en el equipo.

Cuando se alcanza una directiva BARRIER, un hilo esperará en ese punto hasta que todos los otros hilos hayan alcanzado
esa barrera. Todos los hilos reanudan la ejecución en paralelo del código que sigue a la barrera.

Formato:

! $ OMP BARRIER
Fortran

C/C #pragma omp barrier newline


++

Restricciones

Todos los hilos en un equipo (o ninguno) deben ejecutar la región BARRERA.

La secuencia de regiones de trabajo compartido y regiones de barrera encontradas debe ser la misma para cada hilo en un
equipo.

Directivas OpenMP

Construcciones de
sincronización Directiva TASKWAIT
Propósito:

Característica OpenMP 3.1

El constructo TASKWAIT especifica una espera en la finalización de tareas secundarias generadas desde el comienzo de la
tarea actual.

Formato:

! $ OMP TASKWAIT
Fortran

C/C #pragment omp taskwait newline


++

https://computing.llnl.gov/tutorials/openMP/ 26/55
26/6/2018 OpenMP

Restricciones

Como el constructo taskwait no tiene una declaración de lenguaje C como parte de su sintaxis, existen algunas restricciones
sobre su ubicación dentro de un programa. La directiva taskwait puede colocarse solo en un punto donde se permite una
declaración de lenguaje base. La directiva taskwait no se puede usar en lugar de la instrucción que sigue a if, while, do,
switch o label. Consulte el documento de especificaciones de OpenMP 3.1 para más detalles.

Directivas OpenMP

Construcciones de sincronización
Directiva ATOMIC
Propósito:

La directiva ATOMIC especifica que una ubicación de memoria específica se debe actualizar atómicamente, en lugar de dejar
que múltiples hilos intenten escribir en ella. En esencia, esta directiva proporciona una sección mini-CRÍTICA.

Formato:

! $ OMP ATOMIC
Fortran expresión_expresión

#pragma omp atomic newline


C/C
++ expresión_expresión

Restricciones

La directiva se aplica solo a una declaración única e inmediatamente posterior

Una declaración atómica debe seguir una sintaxis específica. Vea las especificaciones más recientes de OpenMP para esto.

Directivas OpenMP

Construcciones de sincronización
Directiva FLUSH
Propósito:

La directiva FLUSH identifica un punto de sincronización en el cual la implementación debe proporcionar una vista
consistente de la memoria. Las variables de rosca visible se escriben nuevamente en la memoria en este punto.

Hay una buena cantidad de discusión sobre esta directiva dentro de los círculos de OpenMP que tal vez desee consultar
para obtener más información. Algo de esto es difícil de entender? Por la API:
Si la intersección de los conjuntos de color de dos flujos realizados por dos subprocesos diferentes no está vacía,
entonces los dos flujos deben completarse como si se tratara de un orden secuencial, visto por todos los subprocesos.
¿Que qué?

Para citar las preguntas frecuentes de openmp.org:

P17: ¿Es necesaria la directiva! $ Omp flush en un sistema coherente de caché?

A17: Sí, la directiva flush es necesaria. Consulte las especificaciones de OpenMP para ver ejemplos de sus usos. La
directiva es necesaria para indicar al compilador que la variable debe escribirse / leerse desde el sistema de memoria, es
decir, que la variable no puede mantenerse en un registro local de la CPU sobre la "declaración" en su código.

La coherencia de la caché garantiza que si una CPU ejecuta una instrucción de lectura o escritura de / a la memoria, todas
las otras CPU en el sistema obtendrán el mismo valor de esa dirección de memoria cuando accedan a ella. Todas las
memorias caché mostrarán un valor coherente. Sin embargo, en el estándar OpenMP debe haber una manera de instruir al
compilador para que realmente inserte la instrucción de lectura / escritura de la máquina y no la posponga. Mantener una
https://computing.llnl.gov/tutorials/openMP/ 27/55
26/6/2018 OpenMP
variable en un registro en un bucle es muy común cuando se produce un código de lenguaje de máquina eficiente para un
bucle.
También vea las especificaciones más recientes de OpenMP para más detalles.

Formato:

! $ OMP FLUSH (lista)


Fortran

C/C #pragma omp flush (list) newline


++

Notas:

La lista opcional contiene una lista de variables nombradas que se eliminarán para evitar el vaciado de todas las variables.
Para los punteros de la lista, tenga en cuenta que el puntero se vacía, no el objeto al que apunta.

Las implementaciones deben garantizar que cualquier modificación previa a las variables visibles del subproceso sea visible
para todos los subprocesos después de este punto; es decir. los compiladores deben restaurar los valores de los registros a
la memoria, es posible que el hardware necesite vaciar los búferes de escritura, etc.

La directiva FLUSH está implícita para las directivas que se muestran en la tabla a continuación. La directiva no está implícita
si una cláusula NOWAIT está presente.

Fortran C / C ++
BARRERA DE barrera
FIN PARALELO paralela - al entrar y salir
crítico y finalidad crítica crítica - al entrar y salir
FIN DO ordenada - al entrar y salir
secciones de extremo para - en las
único extremo secciones de salida - al salir de la
ordenados y ordenados FIN estación - al salir

Directivas OpenMP

Construcciones de sincronización
PEDIDO Directiva
Propósito:

La directiva ORDERED especifica que las iteraciones del bucle cerrado se ejecutarán en el mismo orden que si se
ejecutaran en un procesador serie.

Los hilos necesitarán esperar antes de ejecutar su porción de iteraciones si las iteraciones previas aún no se han
completado.

Usado dentro de un bucle DO / for con una cláusula ORDERED

La directiva ORDERED proporciona una forma de "ajustar" donde el orden se aplicará dentro de un bucle. De lo contrario, no
es obligatorio.

Formato:

! $ OMP DO ORDERED [cláusulas ...]


(región de bucle)

! $ OMP ORDENADO

(bloquear)
Fortran
! $ OMP FINALIZADO

(fin de la región de bucle)


! $ OMP END DO

https://computing.llnl.gov/tutorials/openMP/ 28/55
26/6/2018 OpenMP

C/C #pragma omp para [cláusulas ...]


++ ordenadas (región de bucle)

#pragma omp ordenó nueva línea

structure_block

(endo de la región de bucle)

Restricciones

Una directiva ORDERED solo puede aparecer en la extensión dinámica de las siguientes directivas:
DO o PARALELO DO (Fortran)
para o paralelo para (C / C ++)

Solo se permite un hilo en una sección ordenada en cualquier momento

Es ilegal ramificarse dentro o fuera de un bloque ORDERED.

Una iteración de un ciclo no debe ejecutar la misma directiva ORDERED más de una vez, y no debe ejecutar más de una
directiva ORDERED.

Un ciclo que contiene una directiva ORDERED, debe ser un ciclo con una cláusula ORDERED.

Directivas OpenMP

Directiva THREADPRIVATE
Propósito:

La directiva THREADPRIVATE se utiliza para hacer que las variables de ámbito de archivo global (C / C ++) o los bloques
comunes (Fortran) sean locales y persistentes para un hilo a través de la ejecución de múltiples regiones paralelas.

Formato:

! $ OMP THREADPRIVATE (/ cb /, ...) cb es el nombre de un bloque común


Fortran

C/C #pragma omp threadprivate (lista)


++

Notas:

La directiva debe aparecer después de la declaración de las variables enumeradas / bloques comunes. Cada hilo obtiene su
propia copia del bloque variable / común, por lo que los datos escritos por un hilo no son visibles para otros hilos. Por
ejemplo:

Fortran - Ejemplo de directiva THREADPRIVATE

1 PROGRAMA THREADPRIV
2
3 INTEGER A, B, I, TID, OMP_GET_THREAD_NUM
4 REAL * 4 X
5 COMÚN / C1 / A
6
7 ! $ OMP THREADPRIVATE (/ C1 /, X)
8
9 ! Desactivar explícitamente los hilos dinámicos
10 CALL OMP_SET_DYNAMIC (.FALSE)
11
12 IMPRIMIR *, '1ra. Región Paralela:'
13 ! $ OMP PARALELO PRIVADO (B, TID)
https://computing.llnl.gov/tutorials/openMP/ 29/55
26/6/2018 OpenMP
14 TID = OMP_GET_THREAD_NUM ()
15 A = TIME
16 B = TIME
17 X = 1.1 * TIEMPO + 1.0
18 IMPRIMIR *, 'Subproceso', TID, ': A, B, X =', A, B, X
19 ! $ OMP FINAL PARALELO
20
21 IMPRESIÓN *, '************************************'
22 PRINT *, 'Tema maestro trabajando en serie aquí'
23 IMPRESIÓN *, '************************************'
24
25 PRINT *, '2da región paralela:'
26 ! $ OMP PARALELO PRIVADO (TID)
27 TID = OMP_GET_THREAD_NUM ()
28 IMPRIMIR *, 'Subproceso', TID, ': A, B, X =', A, B, X
29 ! $ OMP FINAL PARALELO
30
31 FIN

Salida:

Primera región paralela:


Hilo 0: A, B, X = 0 0 1.000000000
Subproceso 1: A, B, X = 1 1 2.099999905
Tema 3: A, B, X = 3 3 4.300000191
Tema 2: A, B, X = 2 2 3.200000048
************************************
Tema maestro haciendo trabajo en serie aquí
************************************
Segunda región paralela:
Hilo 0: A, B, X = 0 0 1.000000000
Tema 2: A, B, X = 2 0 3.200000048
Tema 3: A, B, X = 3 0 4.300000191
Subproceso 1: A, B, X = 1 0 2.099999905

C / C ++ - Ejemplo de directiva privada de hilo

1 #include <omp.h>
2
3 int a, b, i, tid;
4 flotar x;
5
6 #pragma omp threadprivate (a, x)
7
8 main (int argc, char * argv []) {
9
10 / * Desactiva explícitamente los hilos dinámicos * /
11 omp_set_dynamic (0);
12
13 printf ("1ra región paralela: \ n");
14 #pragma omp parallel private (b, tid)
15 {
16 tid = omp_get_thread_num ();
17 a = tiempo;
18 b = tiempo;
19 x = 1.1 * tiempo +1.0;
20 printf ("Hilo% d: a, b, x =% d% d% f \ n", tid, a, b, x);
21 } / * fin de la región paralela * /
22
23 printf ("************************************ \ n");
https://computing.llnl.gov/tutorials/openMP/ 30/55
26/6/2018 OpenMP
23 printf ( ************************************ \ n );
24 printf ("Tema maestro haciendo trabajo en serie aquí \ n");
25 printf ("************************************ \ n");
26
27 printf ("2ª región paralela: \ n");
28 #pragment omp parallel private (tid)
29 {
30 tid = omp_get_thread_num ();
31 printf ("Hilo% d: a, b, x =% d% d% f \ n", tid, a, b, x);
32 } / * fin de la región paralela * /
33
34 }

Salida:

Primera región paralela:


Hilo 0: a, b, x = 0 0 1.000000
Subproceso 2: a, b, x = 2 2 3.200000
Tema 3: a, b, x = 3 3 4.300000
Subproceso 1: a, b, x = 1 1 2.100000
************************************
Tema maestro haciendo trabajo en serie aquí
************************************
Segunda región paralela:
Hilo 0: a, b, x = 0 0 1.000000
Tema 3: a, b, x = 3 0 4.300000
Subproceso 1: a, b, x = 1 0 2.100000
Subproceso 2: a, b, x = 2 0 3.200000

En la primera entrada a una región paralela, los datos en las variables THREADPRIVATE y los bloques comunes deben
suponerse indefinidos, a menos que se especifique una cláusula COPYIN en la directiva PARALLEL

Las variables THREADPRIVATE difieren de las PRIVATE (discutidas más adelante) porque pueden persistir entre diferentes
regiones paralelas de un código.

Restricciones

Se garantiza que los datos en objetos THREADPRIVATE persistirán solo si el mecanismo de subprocesos dinámicos está
"desactivado" y el número de subprocesos en diferentes regiones paralelas permanece constante. La configuración
predeterminada de los hilos dinámicos no está definida.

La directiva THREADPRIVATE debe aparecer después de cada declaración de un hilo private variable / common block.

Fortran: solo los bloques comunes con nombre se pueden hacer THREADPRIVATE.

Directivas OpenMP

Cláusulas de atributos de alcance de datos

También se llama Cláusulas de atributos para compartir datos

Una consideración importante para la programación OpenMP es la comprensión y el uso del alcance de los datos

Como OpenMP se basa en el modelo de programación de memoria compartida, la mayoría de las variables se comparten de
forma predeterminada

Las variables globales incluyen:


Fortran: bloques COMUNES, variables de GUARDAR, variables de MÓDULO
C: variables de alcance de archivo, estático

Las variables privadas incluyen:


Variables de índice de bucle
https://computing.llnl.gov/tutorials/openMP/ 31/55
26/6/2018 OpenMP
Variables de pila en subrutinas llamadas desde regiones paralelas
Fortran: variables automáticas dentro de un bloque de instrucciones
Las cláusulas de atributos de alcance de datos de OpenMP se utilizan para definir explícitamente cómo se deben tener en
cuenta las variables. Incluyen:
PRIVADO
FIRSTPRIVATE
LASTPRIVATE
COMPARTIDO
DEFECTO
REDUCCIÓN
COPYIN

Las cláusulas de atributo de ámbito de datos se utilizan junto con varias directivas (PARALELO, DO / para y SECCIONES)
para controlar el alcance de las variables adjuntas.

Estas construcciones proporcionan la capacidad de controlar el entorno de datos durante la ejecución de construcciones
paralelas.

Definen cómo y qué variables de datos en la sección de serie del programa se transfieren a las regiones paralelas del
programa (y viceversa)

Definen qué variables serán visibles para todos los hilos en las regiones paralelas y qué variables se asignarán de
forma privada a todos los hilos.

Las cláusulas de atributos de alcance de datos son efectivas solo dentro de su alcance léxico / estático.

Importante: consulte las últimas especificaciones de OpenMP para obtener detalles importantes y una discusión sobre este
tema.

Se proporciona una tabla de resumen de cláusulas / directivas para mayor comodidad.

Cláusula PRIVADA
Propósito:

La cláusula PRIVATE declara que las variables en su lista son privadas para cada hilo.

Formato:

PRIVADO (lista)
Fortran

C/C privado (lista)


++

Notas:

Las variables PRIVADAS se comportan de la siguiente manera:

Un nuevo objeto del mismo tipo se declara una vez para cada hilo en el equipo

Todas las referencias al objeto original se reemplazan por referencias al nuevo objeto

Se supone que las variables declaradas PRIVATE no están inicializadas para cada hilo

Comparación entre PRIVADO y THREADPRIVATE:

PRIVADO THREADPRIVATE
Elemento de C / C ++: variable C / C ++:
datos Fortran: bloque variable o común Fortran variable : bloque común
Donde Al inicio de la región o grupo de trabajo En declaraciones de cada rutina usando bloque
declarado compartido o alcance de archivo global
¿Persistente? No Sí
Grado Solo léxico - a menos que se transmita como Dinámica
argumento a la subrutina
Inicializado Utilice FIRSTPRIVATE Usa COPYIN
https://computing.llnl.gov/tutorials/openMP/ 32/55
26/6/2018 OpenMP

Cláusula COMPARTIDA
Propósito:

La cláusula SHARED declara las variables en su lista para ser compartidas entre todos los hilos en el equipo.

Formato:

COMPARTIDO (lista)
Fortran

C/C compartido (lista)


++

Notas:

Existe una variable compartida en una sola ubicación de memoria y todos los hilos pueden leer o escribir en esa dirección

Es responsabilidad del programador asegurarse de que los subprocesos múltiples accedan correctamente a las variables
COMPARTIDAS (como a través de secciones CRÍTICAS)

Cláusula DEFAULT
Propósito:

La cláusula DEFAULT permite al usuario especificar un ámbito predeterminado para todas las variables en la extensión léxica
de cualquier región paralela.

Formato:

PREDETERMINADO (PRIVADO | FIRSTPRIVATE | COMPARTIDO | NINGUNO)


Fortran

C/C predeterminado (compartido | ninguno)


++

Notas:

Las variables específicas pueden estar exentas del valor predeterminado utilizando las cláusulas PRIVATE, SHARED,
FIRSTPRIVATE, LASTPRIVATE y REDUCTION

La especificación C / C ++ OpenMP no incluye privado o firstprivate como posible valor predeterminado. Sin embargo, las
implementaciones reales pueden proporcionar esta opción.

El uso de NONE como valor predeterminado requiere que el programador alcance explícitamente todas las variables.

Restricciones

Solo se puede especificar una cláusula DEFAULT en una directiva PARALLEL

Cláusula FIRSTPRIVATE
Propósito:

La cláusula FIRSTPRIVATE combina el comportamiento de la cláusula PRIVATE con la inicialización automática de las
variables en su lista.

Formato:

FIRSTPRIVATE (lista)
Fortran

C/C firstprivate (lista)


++

Notas:
https://computing.llnl.gov/tutorials/openMP/ 33/55
26/6/2018 OpenMP
Notas:

Las variables enumeradas se inicializan de acuerdo con el valor de sus objetos originales antes de ingresar a la construcción
paralela o de trabajo compartido.

Cláusula LASTPRIVATE
Propósito:

La cláusula LASTPRIVATE combina el comportamiento de la cláusula PRIVATE con una copia desde la última iteración o
sección del bucle hasta el objeto variable original.

Formato:

LASTPRIVATE (lista)
Fortran

C/C lastprivate (lista)


++

Notas:

El valor copiado de nuevo en el objeto variable original se obtiene a partir de la última iteración (secuencialmente) o sección
de la construcción adjunta.

Por ejemplo, el miembro del equipo que ejecuta la iteración final para una sección DO, o el miembro del equipo que hace la
última SECCIÓN de un contexto SECCIONES realiza la copia con sus propios valores

Cláusula COPYIN
Propósito:

La cláusula COPYIN proporciona un medio para asignar el mismo valor a las variables THREADPRIVATE para todos los
hilos del equipo.

Formato:

COPYIN (lista)
Fortran

C/C copiando (lista)


++

Notas:

La lista contiene los nombres de las variables para copiar. En Fortran, la lista puede contener los nombres de bloques
comunes y variables nombradas.

La variable de subproceso maestro se utiliza como fuente de copia. Los hilos del equipo se inicializan con su valor al ingresar
al constructo paralelo.

Cláusula COPYPRIVATE
Propósito:

La cláusula COPYPRIVATE se puede usar para transmitir valores adquiridos por un único hilo directamente a todas las
instancias de las variables privadas en los otros hilos.

Asociado con la directiva SINGLE

Consulte el documento de especificaciones de OpenMP más reciente para ver ejemplos y discusiones adicionales.

Formato:

COPYPRIVATE (lista)
Fortran

https://computing.llnl.gov/tutorials/openMP/ 34/55
26/6/2018 OpenMP

C/C copyprivate (lista)


++

Cláusula REDUCCIÓN
Propósito:

La cláusula REDUCTION realiza una operación de reducción en las variables que aparecen en su lista.

Se crea una copia privada para cada variable de lista y se inicializa para cada subproceso. Al final de la reducción, la variable
de reducción se aplica a todas las copias privadas de la variable compartida, y el resultado final se escribe en la variable
compartida global.

Formato:

Fortran REDUCCIÓN (operador: lista)


C/C
reducción (operador: lista)
++

Operadores válidos y valores de inicialización


Operación Fortran C / C ++ Inicialización
Adición + + 0
Multiplicación * * 1
Sustracción - - 0
Lógico Y .y. && 0
O lógico .o. || .falso. / 0
Y a nivel de bit yo y & todos los bits en /
1
O a nivel de bit ior | 0
Exclusivo O bit a bit otro ^ 0
Equivalente .eqv. .cierto.
No Equivalente .neqv. .falso.
Máximo máximo máximo El más negativo #
Mínimo yo yo El positivo más
grande

Ejemplo: REDUCTION - Vector Dot Product:

Las iteraciones del bucle paralelo se distribuirán en bloques de igual tamaño a cada hilo en el equipo (CRONOGRAMA
ESTÁTICO)

Al final de la construcción de bucle paralelo, todos los subprocesos agregarán sus valores de "resultado" para actualizar la
copia global de la secuencia maestra.

Fortran - Ejemplo de cláusula REDUCCIÓN

1 PROGRAMA DOT_PRODUCT
2
3 INTEGER N, CHUNKSIZE, CHUNK, I
4 PARÁMETRO (N = 100)
5 PARÁMETRO (CHUNKSIZE = 10)
6 REAL A (N), B (N), RESULTADO
7
8 ! Algunas inicializaciones
9 DO I = 1 N
https://computing.llnl.gov/tutorials/openMP/ 35/55
26/6/2018 OpenMP
9 DO I = 1, N
10 A (I) = I * 1.0
11 B (I) = I * 2.0
12 ENDDO
13 RESULTADO = 0.0
14 CHUNK = CHUNKSIZE
15
16 ! $ OMP PARALELO HACER
17 ! $ OMP & INCUMPLIMIENTO (COMPARTIDO) PRIVADO (I)
18 ! $ OMP & HORARIO (ESTÁTICO, CHUNK)
19 ! $ OMP & REDUCCIÓN (+: RESULTADO)
20
21 DO I = 1, N
22 RESULTADO = RESULTADO + (A (I) * B (I))
23 ENDDO
24
25 ! $ OMP END PARALELO DO
26
27 IMPRIMIR *, 'Resultado final =', RESULTADO
28 FIN

C / C ++ - Ejemplo de cláusula de reducción

1 #include <omp.h>
2
3 main (int argc, char * argv []) {
4
5 int i, n, fragmento;
6 flotar a [100], b [100], resultado;
7
8 / * Algunas inicializaciones * /
9 n = 100;
10 pedazo = 10;
11 resultado = 0.0;
12 para (i = 0; i <n; i ++) {
13 a [i] = i * 1.0;
14 b [i] = i * 2.0;
15 }
16
17 #pragma omp parallel for \
18 default (shared) private (i) \
19 schedule (static, chunk) \
20 reduction (+: result)
21
22 para (i = 0; i <n; i ++)
23 resultado = resultado + (a [i] * b [i]);
24
25 printf ("Resultado final =% f \ n", resultado);
26
27 }

Restricciones

El tipo de un elemento de lista debe ser válido para el operador de reducción.

Los elementos / variables de la lista no se pueden declarar compartidos o privados.

Las operaciones de reducción pueden no ser asociativas para números reales.

Consulte la API estándar de OpenMP para conocer las restricciones adicionales.

https://computing.llnl.gov/tutorials/openMP/ 36/55
26/6/2018 OpenMP

Directivas OpenMP

Resumen de cláusulas / directivas

La siguiente tabla resume qué cláusulas son aceptadas por las directivas OpenMP.

Directiva
Cláusula PARALELA Hacer para SECCIONES SOLTERO PARALELO
HACER / para SECCIONES PARALELAS
SI

PRIVADO

COMPARTIDO

DEFECTO

FIRSTPRIVATE

LASTPRIVATE

REDUCCIÓN

COPYIN

COPYPRIVATE

PROGRAMAR

ORDENADO

NO, ESPERA

Las siguientes directivas OpenMP no aceptan cláusulas:


DOMINAR
CRÍTICO
BARRERA
ATÓMICO
ENJUAGAR
ORDENADO
THREADPRIVATE

Las implementaciones pueden (y difieren) del estándar en el que las cláusulas son compatibles con cada directiva.

Directivas OpenMP

Reglas vinculantes y anidamiento de directivas

Esta sección se proporciona principalmente como una referencia rápida sobre las reglas que rigen las directivas y el
enlace de OpenMP. Los usuarios deben consultar su documentación de implementación y el estándar OpenMP para
conocer otras reglas y restricciones.

A menos que se indique lo contrario, las reglas se aplican tanto a las implementaciones OpenMP de Fortran como a las de C
/ C ++.

Nota: la API de Fortran también define una serie de reglas de entorno de datos. Esos no han sido reproducidos aquí.

Encuadernación:

Las directivas DO / for, SECTIONS, SINGLE, MASTER y BARRIER se unen al PARALELO que rodea dinámicamente, si
existe. Si no se está ejecutando ninguna región paralela, las directivas no tienen efecto.

La directiva ORDERED se une al DO / que se cierra dinámicamente.

La directiva ATOMIC impone el acceso exclusivo con respecto a las directivas ATOMIC en todos los hilos no solo en el
https://computing.llnl.gov/tutorials/openMP/ 37/55
26/6/2018 OpenMP
La directiva ATOMIC impone el acceso exclusivo con respecto a las directivas ATOMIC en todos los hilos, no solo en el
equipo actual.
La directiva CRITICAL impone el acceso exclusivo con respecto a las directivas CRITICAL en todos los hilos, no solo en el
equipo actual.

Una directiva nunca puede vincularse a ninguna directiva fuera del PARALELO que lo rodea más cercano.

Anidación de directivas:

Una región de trabajo compartido no puede estar estrechamente anidada dentro de una compartición de trabajo, una tarea
explícita, una región crítica, ordenada, atómica o maestra.

Una región de barrera puede no estar estrechamente anidada dentro de una compartición de trabajo, tarea explícita, crítica,
ordenada, atómica o región maestra.

Una región maestra puede no estar estrechamente anidada dentro de una región de tarea compartida, atómica o explícita.

Una región ordenada puede no estar estrechamente anidada dentro de una región de tareas crítica, atómica o explícita.

Una región ordenada debe estar estrechamente anidada dentro de una región de bucle (o región de bucle paralelo) con una
cláusula ordenada.

Una región crítica puede no estar anidada (de cerca o de otro modo) dentro de una región crítica con el mismo nombre.
Tenga en cuenta que esta restricción no es suficiente para evitar un punto muerto.

Las regiones de tareas paralelas, rasantes, críticas, atómicas, de rendimiento de tareas y explícitas pueden no estar
estrechamente anidadas dentro de una región atómica.

Rutinas de biblioteca en tiempo de ejecución

Visión de conjunto:

La API OpenMP incluye un número cada vez mayor de rutinas de biblioteca en tiempo de ejecución.

Estas rutinas se usan para una variedad de propósitos como se muestra en la tabla a continuación:

Rutina Propósito
OMP_SET_NUM_THREADS Establece la cantidad de hilos que se usarán en la próxima región
paralela
OMP_GET_NUM_THREADS Devuelve la cantidad de hilos que se encuentran actualmente en el
equipo que ejecuta la región paralela desde la que se llama
OMP_GET_MAX_THREADS Devuelve el valor máximo que puede devolver una llamada a la
función OMP_GET_NUM_THREADS
OMP_GET_THREAD_NUM Devuelve el número de hilo del hilo, dentro del equipo, haciendo
esta llamada.
OMP_GET_THREAD_LIMIT Devuelve la cantidad máxima de subprocesos OpenMP disponibles
para un programa
OMP_GET_NUM_PROCS Devuelve la cantidad de procesadores disponibles para el
programa
OMP_IN_PARALLEL Se usa para determinar si la sección de código que se está
ejecutando es paralela o no
OMP_SET_DYNAMIC Habilita o deshabilita el ajuste dinámico (por el sistema de tiempo
de ejecución) del número de subprocesos disponibles para la
ejecución de regiones paralelas
OMP_GET_DYNAMIC Se usa para determinar si el ajuste de hilo dinámico está habilitado
o no
OMP_SET_NESTED Se usa para habilitar o deshabilitar el paralelismo anidado
OMP_GET_NESTED Se usa para determinar si el paralelismo anidado está habilitado o
no
https://computing.llnl.gov/tutorials/openMP/ 38/55
26/6/2018 OpenMP

OMP_SET_SCHEDULE Establece la política de programación de bucles cuando se usa


"runtime" como el tipo de programación en la directiva OpenMP
OMP_GET_SCHEDULE Devuelve la política de programación de bucles cuando se usa
"runtime" como el tipo de programación en la directiva OpenMP
OMP_SET_MAX_ACTIVE_LEVELS Establece el número máximo de regiones paralelas anidadas
OMP_GET_MAX_ACTIVE_LEVELS Devuelve el número máximo de regiones paralelas anidadas
OMP_GET_LEVEL Devuelve el nivel actual de regiones paralelas anidadas
OMP_GET_ANCESTOR_THREAD_NUM Devuelve, para un nivel anidado determinado del subproceso
actual, el número de subproceso del subproceso ancestro
OMP_GET_TEAM_SIZE Devuelve, para un nivel anidado dado del hilo actual, el tamaño del
equipo de hilo
OMP_GET_ACTIVE_LEVEL Devuelve el número de regiones paralelas activas anidadas que
encierran la tarea que contiene la llamada
OMP_IN_FINAL Devuelve verdadero si la rutina se ejecuta en la región de tarea
final; de lo contrario, devuelve falso
OMP_INIT_LOCK Inicializa un bloqueo asociado con la variable de bloqueo
OMP_DESTROY_LOCK Desasocia la variable de bloqueo dada de las cerraduras
OMP_SET_LOCK Adquiere la propiedad de un candado
OMP_UNSET_LOCK Libera un candado
OMP_TEST_LOCK Intenta establecer un bloqueo, pero no bloquea si el bloqueo no
está disponible
OMP_INIT_NEST_LOCK Inicializa un bloqueo anidado asociado con la variable de bloqueo
OMP_DESTROY_NEST_LOCK Desasocia la variable de bloqueo anidada de cualquier bloqueo
OMP_SET_NEST_LOCK Adquiere la propiedad de un bloqueo anidado
OMP_UNSET_NEST_LOCK Libera un bloqueo anidado
OMP_TEST_NEST_LOCK Intenta establecer un bloqueo anidado, pero no bloquea si el
bloqueo no está disponible
OMP_GET_WTIME Proporciona una rutina de sincronización de reloj de pared portátil
OMP_GET_WTICK Devuelve un valor de punto flotante de precisión doble igual al
número de segundos entre tics de reloj sucesivos

Para C / C ++, todas las rutinas de la biblioteca en tiempo de ejecución son subrutinas reales. Para Fortran, algunas son en
realidad funciones, y algunas son subrutinas. Por ejemplo:

Fortran FUNCIÓN INTEGER OMP_GET_NUM_THREADS ()


C / C ++ #include <omp.h>
int omp_get_num_threads (void)

Tenga en cuenta que para C / C ++, generalmente necesita incluir el archivo de encabezado <omp.h> .

Las rutinas de Fortran no distinguen entre mayúsculas y minúsculas, pero sí las rutinas de C / C ++.

Para las rutinas / funciones de bloqueo:


Se debe acceder a la variable de bloqueo solo a través de las rutinas de bloqueo
Para Fortran, la variable de bloqueo debe ser de tipo entero y de un tipo lo suficientemente grande como para contener
una dirección.
Para C / C ++, la variable de bloqueo debe tener el tipo omp_lock_t o tipear omp_nest_lock_t , dependiendo de
la función que se use.

Notas de implementación:
Las implementaciones pueden o no admitir todas las características de la API de OpenMP. Por ejemplo, si se admite el
paralelismo anidado, puede ser solo nominal, en el sentido de que una región paralela anidada solo puede tener un
hilo.
Consulte la documentación de su implementación para obtener detalles, o experimente y descubra por sí mismo si no
https://computing.llnl.gov/tutorials/openMP/ 39/55
26/6/2018 OpenMP
p p , p y p
puede encontrarla en la documentación.

Las rutinas de biblioteca en tiempo de ejecución se discuten con más detalle en el Apéndice A .

Variables de entorno

OpenMP proporciona las siguientes variables de entorno para controlar la ejecución de código paralelo.

Todos los nombres de variables de entorno son mayúsculas. Los valores asignados a ellos no distinguen entre mayúsculas y
minúsculas.

OMP_SCHEDULE

Se aplica solo a DO, PARALELO DO (Fortran) y para, paralelo para (C / C ++) directivas que tienen su cláusula de
cronograma establecida en RUNTIME. El valor de esta variable determina cómo se programan las iteraciones del ciclo en los
procesadores. Por ejemplo:

setenv OMP_SCHEDULE "guiado, 4"


setenv OMP_SCHEDULE "dinámico"

OMP_NUM_THREADS

Establece el número máximo de hilos para usar durante la ejecución. Por ejemplo:

setenv OMP_NUM_THREADS 8

OMP_DYNAMIC

Habilita o deshabilita el ajuste dinámico del número de subprocesos disponibles para la ejecución de regiones paralelas. Los
valores válidos son VERDADERO o FALSO. Por ejemplo:

setenv OMP_DYNAMIC TRUE

OMP_PROC_BIND

Habilita o deshabilita los hilos vinculantes para los procesadores. Los valores válidos son VERDADERO o FALSO. Por
ejemplo:

setenv OMP_PROC_BIND TRUE

OMP_NESTED

Habilita o deshabilita el paralelismo anidado. Los valores válidos son VERDADERO o FALSO. Por ejemplo:

setenv OMP_NESTED TRUE

OMP_STACKSIZE

Controla el tamaño de la pila para hilos creados (no maestros). Ejemplos:

setenv OMP_STACKSIZE 2000500B


setenv OMP_STACKSIZE "3000 k"
setenv OMP_STACKSIZE 10M
setenv OMP_STACKSIZE "10 M"
setenv OMP_STACKSIZE "20 m"
setenv OMP_STACKSIZE "1G"
setenv OMP_STACKSIZE 20000

OMP_WAIT_POLICY

Proporciona una pista sobre una implementación de OpenMP sobre el comportamiento deseado de los hilos de espera. Una
implementación OpenMP compatible puede o no cumplir con la configuración de la variable de entorno. Los valores válidos
son ACTIVO y PASIVO. ACTIVE especifica que los subprocesos en espera deberían estar activos, es decir, consumir ciclos
de procesador, mientras se espera. PASSIVE especifica que los subprocesos en espera deben ser principalmente pasivos,
es decir, no consumir ciclos del procesador, mientras se espera. Los detalles de los comportamientos ACTIVO y PASIVO
están definidos en la implementación. Ejemplos:

setenv OMP WAIT POLICY ACTIVE


https://computing.llnl.gov/tutorials/openMP/ 40/55
26/6/2018 OpenMP
_ _
setenv OMP_WAIT_POLICY activo

setenv OMP_WAIT_POLICY PASSIVE


setenv OMP_WAIT_POLICY pasivo

OMP_MAX_ACTIVE_LEVELS

Controla el número máximo de regiones paralelas activas anidadas. El valor de esta variable de entorno debe ser un entero
no negativo. El comportamiento del programa es la implementación definida si el valor solicitado de
OMP_MAX_ACTIVE_LEVELS es mayor que el número máximo de niveles paralelos activos anidados que una
implementación puede admitir, o si el valor no es un entero no negativo. Ejemplo:

setenv OMP_MAX_ACTIVE_LEVELS 2

OMP_THREAD_LIMIT

Establece el número de subprocesos OpenMP para usar para todo el programa OpenMP. El valor de esta variable de entorno
debe ser un entero positivo. El comportamiento del programa es la implementación definida si el valor solicitado de
OMP_THREAD_LIMIT es mayor que el número de subprocesos que una implementación puede admitir, o si el valor no es un
entero positivo. Ejemplo:

setenv OMP_THREAD_LIMIT 8

Tamaño de pila de subprocesos y enlace de subprocesos

Tamaño de pila de subprocesos:

El estándar OpenMP no especifica cuánto espacio de pila debe tener un hilo. En consecuencia, las implementaciones
diferirán en el tamaño predeterminado de la pila de subprocesos.

El tamaño predeterminado de la pila de subprocesos puede ser fácil de agotar. También puede ser no portátil entre los
compiladores. Usando versiones anteriores de compiladores LC como ejemplo:

Compilador Aprox. Límite de pila Aprox. Tamaño de la matriz (dobles)


Icc de Linux, ifort 4 MB 700 x 700
Linux pgcc, pgf90 8 MB 1000 x 1000
Linux gcc, gfortran 2 MB 500 x 500

Los subprocesos que exceden su asignación de pila pueden segmentar o no la falla. Una aplicación puede continuar
ejecutándose mientras se corrompen los datos.

Los códigos enlazados estáticamente pueden estar sujetos a restricciones de pila adicionales.

El shell de inicio de sesión de un usuario también puede restringir el tamaño de la pila

Si su entorno OpenMP admite la variable de entorno OpenMP 3.0 OMP_STACKSIZE ( tratada en la sección anterior),
puede usarla para establecer el tamaño de la pila de subprocesos antes de la ejecución del programa. Por ejemplo:

setenv OMP_STACKSIZE 2000500B


setenv OMP_STACKSIZE "3000 k"
setenv OMP_STACKSIZE 10M
setenv OMP_STACKSIZE "10 M"
setenv OMP_STACKSIZE "20 m"
setenv OMP_STACKSIZE "1G"
setenv OMP_STACKSIZE 20000

De lo contrario, en LC, debería poder usar el siguiente método para clusters de Linux. El ejemplo muestra cómo configurar el
tamaño de la pila de subprocesos en 12 MB, y como precaución, establecer el tamaño de la pila de shell en ilimitado.

setenv KMP_STACKSIZE 12000000


csh / tcsh límite stacksize ilimitado
exportar KMP_STACKSIZE = 12000000
ksh / sh / bash
ulimit -s ilimitado
https://computing.llnl.gov/tutorials/openMP/ 41/55
26/6/2018 OpenMP

Encuadernación de hilo:
En algunos casos, un programa funcionará mejor si sus hilos están vinculados a procesadores / núcleos.

"Enlazar" un hilo a un procesador significa que el sistema operativo programará un hilo para que se ejecute siempre en el
mismo procesador. De lo contrario, los hilos pueden programarse para ejecutarse en cualquier procesador y "rebotar" hacia
adelante y hacia atrás entre los procesadores con cada segmento de tiempo.

También se llama "afinidad de subprocesos" o "afinidad de procesadores"

La vinculación de los subprocesos a los procesadores puede dar como resultado una mejor utilización de la memoria caché,
lo que reduce los costosos accesos a la memoria. Esta es la motivación principal para enlazar hilos a procesadores.

Dependiendo de su plataforma, sistema operativo, compilador e implementación de OpenMP, el enlace de hilos a los
procesadores se puede hacer de diferentes maneras.

La API OpenMP versión 3.1 proporciona una variable de entorno para activar o desactivar el enlace del procesador. Por
ejemplo:

setenv OMP_PROC_BIND TRUE


setenv OMP_PROC_BIND FALSE

En un nivel superior, los procesos también pueden estar vinculados a procesadores.

Se puede encontrar información detallada sobre el proceso y el enlace de subprocesos a los procesadores en los clústeres
de LC Linux en https://lc.llnl.gov/confluence/display/TLCC2/mpibind .

Herramientas de monitoreo, depuración y análisis de rendimiento para OpenMP

Subprocesos de monitoreo y depuración:

Los depuradores varían en su capacidad para manejar los hilos. El depurador TotalView es el depurador recomendado de LC
para programas paralelos. Es muy adecuado para monitorear y depurar programas con hilos.

A continuación, se muestra una captura de pantalla de ejemplo de una sesión de TotalView usando un código OpenMP.
1. Hilo maestro Stack Trace Pane que muestra la rutina original
2. Barras de estado del proceso / subproceso que diferencian subprocesos
3. Tema principal Marco de apilado que muestra las variables compartidas
4. Hilo de trabajo Stack Trace Pane que muestra la rutina descrita.
5. Hilo de trabajo Panel de marco de pila
6. Root Window mostrando todos los hilos
7. Panel de hilos que muestra todos los hilos más el hilo seleccionado

https://computing.llnl.gov/tutorials/openMP/ 42/55
26/6/2018 OpenMP

Consulte el tutorial TotalView Debugger para obtener más detalles.

El comando ps de Linux proporciona varios indicadores para ver la información del hilo. Algunos ejemplos se muestran a
continuación. Vea la página de manual para más detalles.

% ps -Lf
UID PID PPID LWP C NLWP TIEMPO TTY TIEMPO CMD
blaise 22529 28240 22529 0 5 11:31 pts / 53 00:00:00 a.out
blaise 22529 28240 22530 99 5 11:31 pts / 53 00:01:24 a.out
blaise 22529 28240 22531 99 5 11:31 pts / 53 00:01:24 a.out
blaise 22529 28240 22532 99 5 11:31 pts / 53 00:01:24 a.out
https://computing.llnl.gov/tutorials/openMP/ 43/55
26/6/2018 OpenMP
p /
blaise 22529 28240 22533 99 5 11:31 pts / 53 00:01:24 a.out

% ps -T
PID SPID TTY TIME CMD
22529 22529 pts / 53 00:00:00 a.out
22529 22530 pts / 53 00:01:49 a.out
22529 22531 pts / 53 00:01:49 a.out
22529 22532 pts / 53 00:01:49 a.out
22529 22533 pts / 53 00:01:49 a.out

% ps -Lm
PID LWP TTY TIME CMD
22529 - pts / 53 00:18:56 a.out
- 22529 - 00:00:00 -
- 22530 - 00:04:44 -
- 22531 - 00:04:44 -
- 22532 - 00:04:44 -
- 22533 - 00:04:44 -

Los clústeres Linux de LC también proporcionan el comando superior para monitorear procesos en un nodo. Si se usa con
el indicador -H , los hilos contenidos dentro de un proceso serán visibles. Un ejemplo del comando superior -H se
muestra a continuación. El proceso principal es PID 18010 que engendró tres hilos, que se muestran como PID 18012,
18013 y 18014.

Herramientas de análisis de rendimiento:

Hay una variedad de herramientas de análisis de rendimiento que se pueden usar con programas OpenMP. Buscar en la web
generará una gran cantidad de información.

En LC, la lista de herramientas informáticas compatibles se puede encontrar en:


computing.llnl.gov/code/content/software_tools.php .

Estas herramientas varían significativamente en su complejidad, funcionalidad y curva de aprendizaje. Cubrirlos en detalle
está más allá del alcance de este tutorial.

Algunas herramientas que vale la pena investigar, específicamente para los códigos OpenMP, incluyen:
Abierto | Speed Shop
TAU
PAPI
Amplificador Intel VTune
ThreadSpotter

OpenMP Ejercicio 3

Clasificado
https://computing.llnl.gov/tutorials/openMP/ 44/55
26/6/2018 OpenMP
Clasificado

Visión de conjunto:

Inicie sesión en el grupo de talleres, si aún no ha iniciado sesión


Ejemplo de directiva huérfana: revisar, compilar, ejecutar
Obtener información del entorno de implementación OpenMP
Programas híbridos OpenMP + MPI
Echa un vistazo a los programas de "errores"

IR AL EJERCICIO AQUÍ

Esto completa el tutorial.


Complete el formulario de evaluación en línea, a menos que esté haciendo el ejercicio, en cuyo caso
complételo al final del ejercicio.

¿A dónde te gustaría ir ahora?


Ejercicio
Agenda
Volver a la cima

Referencias y más información

Autor: Blaise Barney , Livermore Computing.

El sitio web de OpenMP, que incluye los documentos de la interfaz del programa de la aplicación C / C ++ y Fortran.
www.openmp.org

Apéndice A: Rutinas de biblioteca en tiempo de ejecución

OMP_SET_NUM_THREADS
Propósito:

Establece la cantidad de hilos que se usarán en la próxima región paralela. Debe ser un número entero positivo.

Formato:
https://computing.llnl.gov/tutorials/openMP/ 45/55
26/6/2018 OpenMP

Fortran SUBROUTINE OMP_SET_NUM_THREADS (scalar_integer_expression)


C/C #include <omp.h>
++ void omp_set_num_threads (int num_threads)

Notas y restricciones:

El mecanismo de hilos dinámicos modifica el efecto de esta rutina.


Habilitado: especifica el número máximo de hilos que se pueden usar para cualquier región paralela mediante el
mecanismo de hilos dinámicos.
Deshabilitado: especifica el número exacto de subprocesos que se usarán hasta la próxima llamada a esta rutina.

Esta rutina solo se puede invocar a partir de las partes en serie del código

Esta llamada tiene prioridad sobre la variable de entorno OMP_NUM_THREADS

OMP_GET_NUM_THREADS
Propósito:

Devuelve la cantidad de hilos que se encuentran actualmente en el equipo que ejecuta la región paralela desde la que se
llama.

Formato:

Fortran FUNCIÓN INTEGER OMP_GET_NUM_THREADS ()


C/C #include <omp.h>
++ int omp_get_num_threads (void)

Notas y restricciones:

Si esta llamada se realiza desde una parte en serie del programa, o una región paralela anidada que se serializa, devolverá
1.

El número predeterminado de subprocesos depende de la implementación.

OMP_GET_MAX_THREADS
Propósito:

Devuelve el valor máximo que puede devolver una llamada a la función OMP_GET_NUM_THREADS.

Fortran FUNCIÓN INTEGER OMP_GET_MAX_THREADS ()


C/C #include <omp.h>
++ int omp_get_max_threads (void)

Notas y restricciones:

En general, refleja la cantidad de subprocesos configurados por la variable de entorno OMP_NUM_THREADS o la rutina de
la biblioteca OMP_SET_NUM_THREADS ().

Puede ser llamado desde ambas regiones de código en serie y paralelas.

OMP_GET_THREAD_NUM
Propósito:

Devuelve el número de hilo del hilo, dentro del equipo, haciendo esta llamada. Este número estará entre 0 y
OMP_GET_NUM_THREADS-1. El hilo maestro del equipo es el hilo 0

Formato:

Fortran FUNCIÓN INTEGER OMP GET THREAD NUM ()


https://computing.llnl.gov/tutorials/openMP/ 46/55
26/6/2018 OpenMP
Fortran FUNCIÓN INTEGER OMP_GET_THREAD_NUM ()
C/C #include <omp.h>
++ int omp_get_thread_num (void)

Notas y restricciones:

Si se llama desde una región paralela anidada, o una región en serie, esta función devolverá 0.

Ejemplos:

El ejemplo 1 es la forma correcta de determinar el número de subprocesos en una región paralela.


El ejemplo 2 es incorrecto: la variable TID debe ser PRIVADA
El ejemplo 3 es incorrecto: la llamada OMP_GET_THREAD_NUM está fuera de la región paralela

Fortran: determinar el número de hilos en una región paralela

Ejemplo 1: correcto

PROGRAMA HOLA

INTEGER TID, OMP_GET_THREAD_NUM

! $ OMP PARALELO PRIVADO (TID)

TID = OMP_GET_THREAD_NUM ()
IMPRIMIR *, 'Hello World from thread =', TID

...

! $ OMP FINAL PARALELO

FIN

Ejemplo 2: incorrecto

PROGRAMA HOLA

INTEGER TID, OMP_GET_THREAD_NUM

! $ OMP PARALELO

TID = OMP_GET_THREAD_NUM ()
IMPRIMIR *, 'Hello World from thread =', TID

...

! $ OMP FINAL PARALELO

FIN

Ejemplo 3: incorrecto

PROGRAMA HOLA

INTEGER TID, OMP_GET_THREAD_NUM

TID = OMP_GET_THREAD_NUM ()
IMPRIMIR *, 'Hello World from thread =', TID

! $ OMP PARALELO

...

! $ OMP FINAL PARALELO

FIN

https://computing.llnl.gov/tutorials/openMP/ 47/55
26/6/2018 OpenMP

OMP_GET_THREAD_LIMIT

Propósito:

Devuelve la cantidad máxima de subprocesos OpenMP disponibles para un programa.

Formato:

Fortran FUNCIÓN INTEGER OMP_GET_THREAD_LIMIT


C/C #include <omp.h>
++ int omp_get_thread_limit (void)

Notas:

También vea la variable de entorno OMP_THREAD_LIMIT .

OMP_GET_NUM_PROCS
Propósito:

Devuelve la cantidad de procesadores disponibles para el programa.

Formato:

Fortran FUNCIÓN INTEGER OMP_GET_NUM_PROCS ()


C/C #include <omp.h>
++ int omp_get_num_procs (void)

OMP_IN_PARALLEL
Propósito:

Se puede llamar para determinar si la sección de código que se está ejecutando es paralela o no.

Formato:

Fortran FUNCIÓN LÓGICA OMP_IN_PARALLEL ()


C/C #include <omp.h>
++ int omp_in_parallel (void)

Notas y restricciones:

Para Fortran, esta función devuelve .TRUE. si se llama desde la extensión dinámica de una región que se ejecuta en
paralelo, y .FALSE. de otra manera. Para C / C ++, devolverá un entero distinto de cero si es paralelo, y cero de lo contrario.

OMP_SET_DYNAMIC
Propósito:

Habilita o deshabilita el ajuste dinámico (por el sistema de tiempo de ejecución) del número de subprocesos disponibles para
la ejecución de regiones paralelas.

Formato:

Fortran SUBROUTINE OMP_SET_DYNAMIC (scalar_logical_expression)


C/C #include <omp.h>
++ void omp_set_dynamic (int dynamic_threads)

Notas y restricciones:

Para Fortran, si se llama con .TRUE. a continuación, el entorno de tiempo de ejecución puede ajustar automáticamente el
número de subprocesos disponibles para regiones paralelas posteriores. Si se llama con .FALSE., El ajuste dinámico está
https://computing.llnl.gov/tutorials/openMP/ 48/55
26/6/2018 OpenMP
deshabilitado.

Para C / C ++, si dynamic_threads evalúa a no cero, entonces el mecanismo está habilitado; de lo contrario, está
deshabilitado.

La subrutina OMP_SET_DYNAMIC tiene prioridad sobre la variable de entorno OMP_DYNAMIC.

La configuración predeterminada depende de la implementación.

Debe ser llamado desde una sección serial del programa.

OMP_GET_DYNAMIC
Propósito:

Se usa para determinar si el ajuste dinámico del hilo está habilitado o no.

Formato:

Fortran FUNCIÓN LÓGICA OMP_GET_DYNAMIC ()


C/C #include <omp.h>
++ int omp_get_dynamic (void)

Notas y restricciones:

Para Fortran, esta función devuelve .TRUE. si el ajuste de hilo dinámico está habilitado, y .FALSE. de otra manera.

Para C / C ++, se devolverá un valor distinto de cero si se habilita el ajuste de hilo dinámico, y cero de lo contrario.

OMP_SET_NESTED
Propósito:

Se usa para habilitar o deshabilitar el paralelismo anidado.

Formato:

Fortran SUBROUTINE OMP_SET_NESTED (scalar_logical_expression)


C/C #include <omp.h>
++ void omp_set_nested (int anidado)

Notas y restricciones:

Para Fortran, llamar a esta función con .FALSE. desactivará el paralelismo anidado y llamará con .TRUE. lo habilitará

Para C / C ++, si anidado se evalúa como distinto de cero, se habilita el paralelismo anidado; de lo contrario, está
deshabilitado.

El valor predeterminado es que el paralelismo anidado esté deshabilitado.

Esta llamada tiene prioridad sobre la variable de entorno OMP_NESTED

OMP_GET_NESTED
Propósito:

Se usa para determinar si el paralelismo anidado está habilitado o no.

Formato:

Fortran FUNCIÓN LÓGICA OMP_GET_NESTED


C/C #include <omp.h>
++ int omp_get_nested (void)

https://computing.llnl.gov/tutorials/openMP/ 49/55
26/6/2018 OpenMP
Notas y restricciones:

Para Fortran, esta función devuelve .TRUE. si el paralelismo anidado está habilitado, y .FALSE. de otra manera.

Para C / C ++, se devolverá un valor distinto de cero si el paralelismo anidado está habilitado, y cero de lo contrario.

OMP_SET_SCHEDULE
Propósito:

Esta rutina establece el tipo de programación que se aplica cuando la directiva de ciclo especifica un cronograma de tiempo
de ejecución.

Formato:

SUBROUTINE OMP_SET_SCHEDULE (KIND, MODIFIER)


Fortran INTEGER (KIND = OMP_SCHED_KIND) KIND
INTEGER MODIFY
C/C #include <omp.h>
++ void omp_set_schedule (modificador omp_sched_t kind, int)

OMP_GET_SCHEDULE
Propósito:

Esta rutina devuelve la programación que se aplica cuando la directiva de ciclo especifica un cronograma de tiempo de
ejecución.

Formato:

SUBROUTINE OMP_GET_SCHEDULE (KIND, MODIFIER)


Fortran INTEGER (KIND = OMP_SCHED_KIND) KIND
INTEGER MODIFY
C/C #include <omp.h>
++ void omp_get_schedule (modificador omp_sched_t * kind, int *)

OMP_SET_MAX_ACTIVE_LEVELS
Propósito:

Esta rutina limita el número de regiones paralelas activas anidadas.

Formato:

SUBROUTINE OMP_SET_MAX_ACTIVE_LEVELS (MAX_LEVELS)


Fortran
INTEGER MAX_LEVELS
C/C #include <omp.h>
++ void omp_set_max_active_levels (int max_levels)

Notas y restricciones:

Si el número de niveles paralelos solicitados excede el número de niveles de paralelismo soportados por la implementación,
el valor se establecerá en el número de niveles paralelos admitidos por la implementación.

Esta rutina tiene el efecto descrito solo cuando se llama desde la parte secuencial del programa. Cuando se llama desde
dentro de una región paralela explícita, el efecto de esta rutina se define en la implementación.

OMP_GET_MAX_ACTIVE_LEVELS
Propósito:

Esta rutina devuelve el número máximo de regiones paralelas activas anidadas.


https://computing.llnl.gov/tutorials/openMP/ 50/55
26/6/2018 OpenMP

Formato:
Fortran FUNCIÓN INTEGER OMP_GET_MAX_ACTIVE_LEVELS ()
C/C #include <omp.h>
++ int omp_get_max_active_levels (void)

OMP_GET_LEVEL
Propósito:

Esta rutina devuelve el número de regiones paralelas anidadas que encierra la tarea que contiene la llamada.

Formato:

Fortran FUNCIÓN INTEGER OMP_GET_LEVEL ()


C/C #include <omp.h>
++ int omp_get_level (void)

Notas y restricciones:

La rutina omp_get_level devuelve el número de regiones paralelas anidadas (ya sean activas o inactivas) que encierran la
tarea que contiene la llamada, sin incluir la región paralela implícita. La rutina siempre devuelve un entero no negativo y
devuelve 0 si se llama desde la parte secuencial del programa.

OMP_GET_ANCESTOR_THREAD_NUM
Propósito:

Esta rutina devuelve, para un nivel anidado determinado del subproceso actual, el número de subproceso del ancestro o el
subproceso actual.

Formato:

FUNCIÓN INTEGER OMP_GET_ANCESTOR_THREAD_NUM (LEVEL)


Fortran
NIVEL INTEGER
C/C #include <omp.h>
++ int omp_get_ancestor_thread_num (nivel int)

Notas y restricciones:

Si el nivel de jerarquía solicitado está fuera del rango de 0 y el nivel de jerarquía del subproceso actual, como lo devuelve la
rutina omp_get_level, la rutina devuelve -1.

OMP_GET_TEAM_SIZE
Propósito:

Esta rutina devuelve, para un nivel anidado dado del hilo actual, el tamaño del equipo de hilo al que pertenece el antecesor o
el hilo actual.

Formato:

FUNCIÓN INTEGER OMP_GET_TEAM_SIZE (NIVEL)


Fortran
NIVEL INTEGER
C/C #include <omp.h>
++ int omp_get_team_size (nivel int);

Notas y restricciones:

Si el nivel anidado solicitado está fuera del rango de 0 y el nivel anidado del hilo actual, como lo devuelve la rutina
omp_get_level, la rutina devuelve -1. Las regiones paralelas inactivas se consideran regiones paralelas activas ejecutadas
con un subproceso.
https://computing.llnl.gov/tutorials/openMP/ 51/55
26/6/2018 OpenMP
p

OMP_GET_ACTIVE_LEVEL
Propósito:

La rutina omp_get_active_level devuelve el número de regiones paralelas activas anidadas que encierran la tarea que
contiene la llamada.

Formato:

Fortran FUNCIÓN INTEGER OMP_GET_ACTIVE_LEVEL ()


C/C #include <omp.h>
++ int omp_get_active_level (void);

Notas y restricciones:

La rutina siempre devuelve un entero no negativo, y devuelve 0 si se llama desde la parte secuencial del programa.

OMP_IN_FINAL
Propósito:

Esta rutina devuelve verdadero si la rutina se ejecuta en una región de tarea final; de lo contrario, devuelve falso.

Formato:

Fortran FUNCIÓN LÓGICA OMP_IN_FINAL ()


C/C #include <omp.h>
++ int omp_in_final (void)

OMP_INIT_LOCK
OMP_INIT_NEST_LOCK
Propósito:

Esta subrutina inicializa un bloqueo asociado con la variable de bloqueo.

Formato:

SUBROUTINE OMP_INIT_LOCK (var)


Fortran
SUBROUTINE OMP_INIT_NEST_LOCK (var)
#include <omp.h>
C/C void omp_init_lock (omp_lock_t * lock)
++ void omp_init_nest_lock (omp_nest_lock_t * lock)

Notas y restricciones:

El estado inicial está desbloqueado

Para Fortran, var debe ser un número entero lo suficientemente grande como para contener una dirección, como INTEGER *
8 en sistemas de 64 bits.

OMP_DESTROY_LOCK
OMP_DESTROY_NEST_LOCK
Propósito:

Esta subrutina desasocia la variable de bloqueo dada de cualquier bloqueo.

Formato:

https://computing.llnl.gov/tutorials/openMP/ 52/55
26/6/2018 OpenMP
Fortran SUBROUTINE OMP_DESTROY_LOCK (var)
SUBROUTINE OMP_DESTROY_NEST_LOCK (var)
#include <omp.h>
C/C
void omp_destroy_lock (omp_lock_t * lock)
++ void omp_destroy_nest_lock (omp_nest_lock_t * lock)

Notas y restricciones:

Es ilegal llamar a esta rutina con una variable de bloqueo que no se inicializa.

Para Fortran, var debe ser un número entero lo suficientemente grande como para contener una dirección, como INTEGER *
8 en sistemas de 64 bits.

OMP_SET_LOCK
OMP_SET_NEST_LOCK
Propósito:

Esta subrutina obliga al subproceso que se ejecuta a esperar hasta que esté disponible el bloqueo especificado. A un
subproceso se le otorga la propiedad de un bloqueo cuando esté disponible.

Formato:

SUBROUTINE OMP_SET_LOCK (var)


Fortran
SUBROUTINE OMP_SET_NEST_LOCK (var)
#include <omp.h>
C/C void omp_set_lock (omp_lock_t * lock)
++
void omp_set_nest__lock (omp_nest_lock_t * lock)

Notas y restricciones:

Es ilegal llamar a esta rutina con una variable de bloqueo que no se inicializa.

Para Fortran, var debe ser un número entero lo suficientemente grande como para contener una dirección, como INTEGER *
8 en sistemas de 64 bits.

OMP_UNSET_LOCK
OMP_UNSET_NEST_LOCK
Propósito:

Esta subrutina libera el bloqueo de la subrutina de ejecución.

Formato:

SUBROUTINE OMP_UNSET_LOCK (var)


Fortran
SUBROUTINE OMP_UNSET_NEST_LOCK (var)
#include <omp.h>
C/C
void omp_unset_lock (omp_lock_t * lock)
++ void omp_unset_nest__lock (omp_nest_lock_t * lock)

Notas y restricciones:

Es ilegal llamar a esta rutina con una variable de bloqueo que no se inicializa.

Para Fortran, var debe ser un número entero lo suficientemente grande como para contener una dirección, como INTEGER *
8 en sistemas de 64 bits.

OMP_TEST_LOCK
OMP_TEST_NEST_LOCK
Propósito:
https://computing.llnl.gov/tutorials/openMP/ 53/55
26/6/2018 OpenMP

Esta subrutina intenta establecer un bloqueo, pero no bloquea si el bloqueo no está disponible.

Formato:

SUBROUTINE OMP_TEST_LOCK (var)


Fortran
SUBROUTINE OMP_TEST_NEST_LOCK (var)
#include <omp.h>
C/C int omp_test_lock (omp_lock_t * lock)
++
int omp_test_nest__lock (omp_nest_lock_t * lock)

Notas y restricciones:

Para Fortran, .TRUE. se devuelve si el bloqueo se estableció correctamente, de lo contrario .FALSE. es regresado.

Para Fortran, var debe ser un número entero lo suficientemente grande como para contener una dirección, como INTEGER *
8 en sistemas de 64 bits.

Para C / C ++, se devuelve un valor distinto de cero si el bloqueo se configuró correctamente; de lo contrario, se devuelve
cero.

Es ilegal llamar a esta rutina con una variable de bloqueo que no se inicializa.

OMP_GET_WTIME
Propósito:

Proporciona una rutina de sincronización de reloj de pared portátil

Devuelve un valor de punto flotante de precisión doble igual al número de segundos transcurridos desde algún punto en el
pasado. Normalmente se usa en "pares" con el valor de la primera llamada restada del valor de la segunda llamada para
obtener el tiempo transcurrido para un bloque de código.

Diseñado para ser "por hilo" veces, y por lo tanto puede no ser globalmente consistente en todos los hilos en un equipo -
depende de lo que está haciendo un hilo en comparación con otros hilos.

Formato:

Fortran FUNCIÓN DE DOBLE PRECISIÓN OMP_GET_WTIME ()


C/C #include <omp.h>
++ doble omp_get_wtime (void)

OMP_GET_WTICK
Propósito:

Proporciona una rutina de sincronización de reloj de pared portátil

Devuelve un valor de punto flotante de precisión doble igual al número de segundos entre tics de reloj sucesivos.

Formato:

Fortran FUNCIÓN DE DOBLE PRECISIÓN OMP_GET_WTICK ()


C/C #include <omp.h>
++ doble omp_get_wtick (void)

https://computing.llnl.gov/tutorials/openMP/
Última modificación: 14/06/2018 15:06:32 blaiseb@llnl.gov
UCRL-MI-133316

Este trabajo fue realizado bajo los auspicios del Departamento de Energía de EE. UU. Por Lawrence Livermore National Laboratory bajo el Contrato DE-AC52-07NA27344.

https://computing.llnl.gov/tutorials/openMP/ 54/55
26/6/2018 OpenMP

https://computing.llnl.gov/tutorials/openMP/ 55/55

Vous aimerez peut-être aussi