OpenMP es administrado por el consorcio tecnológico sin fines de lucro OpenMP Architecture Review Board (o OpenMP ARB ), definido conjuntamente por una amplia franja de proveedores líderes de hardware y software de computadoras, incluidos Arm , AMD , IBM , Intel , Cray , HP , Fujitsu , Nvidia , NEC , Red Hat , Texas Instruments y Oracle Corporation . [1]
Una aplicación construida con el modelo híbrido de programación paralela puede ejecutarse en un clúster de computadoras que utilice tanto OpenMP como Message Passing Interface (MPI), de modo que OpenMP se utiliza para el paralelismo dentro de un nodo (multinúcleo) mientras que MPI se utiliza para el paralelismo entre nodos. También se han hecho esfuerzos para ejecutar OpenMP en sistemas de memoria compartida distribuidos por software , [6] para traducir OpenMP a MPI [7] [8]
y para extender OpenMP para sistemas de memoria no compartida. [9]
Diseño
OpenMP es una implementación de subprocesos múltiples , un método de paralelización mediante el cual un subproceso principal (una serie de instrucciones ejecutadas consecutivamente) bifurca una cantidad específica de subprocesos y el sistema divide una tarea entre ellos. Luego, los subprocesos se ejecutan simultáneamente y el entorno de ejecución asigna subprocesos a diferentes procesadores.
La sección de código que se va a ejecutar en paralelo se marca en consecuencia, con una directiva del compilador que hará que los hilos se formen antes de que se ejecute la sección. [3] Cada hilo tiene un ID asociado que se puede obtener mediante una función (llamada omp_get_thread_num()). El ID del hilo es un número entero y el hilo principal tiene un ID de 0 . Después de la ejecución del código paralelizado, los hilos se vuelven a unir al hilo principal, que continúa hasta el final del programa.
De forma predeterminada, cada subproceso ejecuta la sección paralelizada del código de forma independiente. Se pueden utilizar estructuras de trabajo compartido para dividir una tarea entre los subprocesos de modo que cada uno ejecute la parte del código que le corresponde. De esta forma, se puede lograr el paralelismo de tareas y de datos utilizando OpenMP.
El entorno de ejecución asigna subprocesos a los procesadores en función del uso, la carga de la máquina y otros factores. El entorno de ejecución puede asignar la cantidad de subprocesos en función de variables de entorno , o el código puede hacerlo mediante funciones. Las funciones OpenMP se incluyen en un archivo de encabezado denominado omp.h en C / C++ .
Historia
En octubre de 1997, la OpenMP Architecture Review Board (ARB) publicó sus primeras especificaciones API, OpenMP para Fortran 1.0. En octubre del año siguiente, publicaron el estándar C/C++. En 2000, se publicó la versión 2.0 de las especificaciones Fortran y, en 2002, la versión 2.0 de las especificaciones C/C++. La versión 2.5 es una especificación combinada C/C++/Fortran que se publicó en 2005. [ cita requerida ]
Hasta la versión 2.0, OpenMP especificaba principalmente formas de paralelizar bucles altamente regulares, como los que ocurren en la programación numérica orientada a matrices , donde el número de iteraciones del bucle se conoce en el momento de la entrada. Esto se reconoció como una limitación y se agregaron varias extensiones de paralelismo de tareas a las implementaciones. En 2005, se formó un esfuerzo para estandarizar el paralelismo de tareas, que publicó una propuesta en 2007, inspirándose en las características de paralelismo de tareas en Cilk , X10 y Chapel . [10]
La versión 3.0 se lanzó en mayo de 2008. Entre las nuevas características de la versión 3.0 se incluye el concepto de tareas y la construcción de tareas , [11] ampliando significativamente el alcance de OpenMP más allá de las construcciones de bucle paralelo que conformaban la mayor parte de OpenMP 2.0. [12]
La versión actual es la 5.2, lanzada en noviembre de 2021. [15]
La versión 6.0 se lanzará en 2024. [16]
Tenga en cuenta que no todos los compiladores (y sistemas operativos) admiten el conjunto completo de características de las últimas versiones.
Elementos básicos
Los elementos centrales de OpenMP son las construcciones para la creación de subprocesos, la distribución de la carga de trabajo (reparto del trabajo), la gestión del entorno de datos, la sincronización de subprocesos, las rutinas de ejecución a nivel de usuario y las variables de entorno.
En C/C++, OpenMP utiliza #pragmas . Los pragmas específicos de OpenMP se enumeran a continuación.
Creación de hilo
El pragma omp parallel se utiliza para bifurcar subprocesos adicionales para realizar el trabajo incluido en la construcción en paralelo. El subproceso original se denominará subproceso maestro con ID de subproceso 0.
Utilice el indicador -fopenmp para compilar usando GCC:
$ gcc -fopenmp hola.c -o hola -ldl
Salida en una computadora con dos núcleos y, por lo tanto, dos subprocesos:
Hola Mundo.Hola Mundo.
Sin embargo, la salida también puede estar distorsionada debido a la condición de carrera causada por los dos subprocesos que comparten la salida estándar .
Hola, hola, mundo.Enero.
Si printfes atómico depende de la implementación subyacente [17] a diferencia de C++11 std::cout, que es seguro para subprocesos de manera predeterminada. [18]
Constructos de reparto de trabajo
Se utiliza para especificar cómo asignar trabajo independiente a uno o todos los hilos.
omp for o omp do : se utilizan para dividir las iteraciones del bucle entre los subprocesos, también llamadas construcciones de bucle.
Secciones : asignar bloques de código consecutivos pero independientes a diferentes subprocesos
single : especifica un bloque de código que es ejecutado por un solo hilo, se implica una barrera al final
maestro : similar a simple, pero el bloque de código será ejecutado solo por el hilo maestro y no hay ninguna barrera implícita al final.
Ejemplo: inicializar el valor de una matriz grande en paralelo, utilizando cada hilo para hacer parte del trabajo
int principal ( int argc , char ** argv ) { int a [ 100000 ];#pragma omp paralelo para para ( int i = 0 ; i < 100000 ; i ++ ) { a [ i ] = 2 * i ; }devuelve 0 ; }
Este ejemplo es vergonzosamente paralelo y depende únicamente del valor de i . El indicador paralelo for de OpenMP le indica al sistema OpenMP que divida esta tarea entre sus subprocesos de trabajo. Cada subproceso recibirá una versión única y privada de la variable. [19] Por ejemplo, con dos subprocesos de trabajo, a un subproceso se le puede entregar una versión de i que se ejecuta desde 0 hasta 49999 mientras que el segundo obtiene una versión que se ejecuta desde 50000 hasta 99999.
Directivas variantes
Las directivas de variantes son una de las principales características introducidas en la especificación OpenMP 5.0 para facilitar a los programadores la mejora de la portabilidad del rendimiento. Permiten la adaptación de pragmas OpenMP y código de usuario en tiempo de compilación. La especificación define rasgos para describir construcciones OpenMP activas, dispositivos de ejecución y funcionalidad proporcionada por una implementación, selectores de contexto basados en los rasgos y condiciones definidas por el usuario, y directivas metadirectivas y de declaración para que los usuarios programen la misma región de código con directivas de variantes.
La metadirectiva es una directiva ejecutable que se resuelve condicionalmente en otra directiva en tiempo de compilación seleccionando entre múltiples variantes de directiva basadas en características que definen una condición o contexto de OpenMP.
La directiva de declaración de variante tiene una funcionalidad similar a la metadirectiva pero selecciona una variante de función en el sitio de la llamada según el contexto o las condiciones definidas por el usuario.
El mecanismo proporcionado por las dos directivas variantes para seleccionar variantes es más cómodo de usar que el preprocesamiento de C/C++ ya que admite directamente la selección de variantes en OpenMP y permite que un compilador de OpenMP analice y determine la directiva final a partir de las variantes y el contexto.
// Adaptación de código mediante directivas de preprocesamientoint v1 [ N ], v2 [ N ], v3 [ N ]; #si se define (nvptx) #pragma omp objetivo equipos distribuir paralelo para map(to:v1,v2) map(from:v3) para ( int i = 0 ; i < N ; i ++ ) v3 [ i ] = v1 [ i ] * v2 [ i ]; #sino #pragma omp objetivo paralelo para map(to:v1,v2) map(from:v3) para ( int i = 0 ; i < N ; i ++ ) v3 [ i ] = v1 [ i ] * v2 [ i ]; #finsi// Adaptación de código mediante metadirectiva en OpenMP 5.0int v1 [ N ], v2 [ N ], v3 [ N ]; #pragma omp target map(to:v1,v2) map(from:v3) #pragma omp metadirectiva \ cuando(dispositivo={arch(nvptx)}: los equipos de destino distribuyen en paralelo para)\ predeterminado(objetivo paralelo para) para ( int i = 0 ; i < N ; i ++ ) v3 [ i ] = v1 [ i ] * v2 [ i ];
Cláusulas
Dado que OpenMP es un modelo de programación de memoria compartida, la mayoría de las variables en el código OpenMP son visibles para todos los subprocesos de forma predeterminada. Pero a veces las variables privadas son necesarias para evitar condiciones de carrera y existe la necesidad de pasar valores entre la parte secuencial y la región paralela (el bloque de código ejecutado en paralelo), por lo que la gestión del entorno de datos se introduce como cláusulas de atributos de uso compartido de datos agregándolas a la directiva OpenMP. Los diferentes tipos de cláusulas son:
Cláusulas de atributos de intercambio de datos
shared : los datos declarados fuera de una región paralela son compartidos, lo que significa que son visibles y accesibles para todos los subprocesos simultáneamente. De manera predeterminada, se comparten todas las variables en la región de trabajo compartido, excepto el contador de iteraciones del bucle.
privado : los datos declarados dentro de una región paralela son privados para cada subproceso, lo que significa que cada subproceso tendrá una copia local y la usará como una variable temporal. Una variable privada no se inicializa y el valor no se mantiene para su uso fuera de la región paralela. De manera predeterminada, los contadores de iteración de bucle en las construcciones de bucle de OpenMP son privados.
default : permite al programador indicar que el alcance de datos predeterminado dentro de una región paralela será shared o none para C/C++, o shared , firstprivate , private o none para Fortran. La opción none obliga al programador a declarar cada variable en la región paralela utilizando las cláusulas de atributo de uso compartido de datos.
firstprivate : como privado excepto que se inicializa con el valor original.
lastprivate : como private excepto que el valor original se actualiza después de la construcción.
reducción : una forma segura de unir el trabajo de todos los hilos después de la construcción.
Cláusulas de sincronización
crítico : el bloque de código incluido será ejecutado por un solo subproceso a la vez, y no por varios subprocesos simultáneamente. Se utiliza a menudo para proteger datos compartidos de condiciones de carrera .
atómico : la actualización de memoria (escritura o lectura-modificación-escritura) en la siguiente instrucción se realizará de forma atómica. No hace que toda la instrucción sea atómica; solo la actualización de memoria es atómica. Un compilador puede usar instrucciones de hardware especiales para un mejor rendimiento que cuando se usa critical .
ordenado : el bloque estructurado se ejecuta en el orden en el que se ejecutarían las iteraciones en un bucle secuencial
barrera : cada hilo espera hasta que todos los demás hilos de un equipo hayan llegado a este punto. Una construcción de trabajo compartido tiene una sincronización de barrera implícita al final.
nowait : especifica que los subprocesos que completan el trabajo asignado pueden continuar sin esperar a que todos los subprocesos del equipo terminen. En ausencia de esta cláusula, los subprocesos encuentran una sincronización de barrera al final de la construcción de trabajo compartido.
Cláusulas de programación
schedule (tipo, fragmento) : esto es útil si la construcción de reparto de trabajo es un bucle do o for. Las iteraciones en la construcción de reparto de trabajo se asignan a subprocesos según el método de programación definido por esta cláusula. Los tres tipos de programación son:
static : Aquí, a todos los subprocesos se les asignan iteraciones antes de ejecutar las iteraciones del bucle. Las iteraciones se dividen entre los subprocesos de manera equitativa de forma predeterminada. Sin embargo, si se especifica un número entero para el parámetro chunk, se asignará un número de iteraciones contiguas a un subproceso en particular.
dynamic : Aquí, algunas de las iteraciones se asignan a un número menor de subprocesos. Una vez que un subproceso en particular finaliza su iteración asignada, vuelve a buscar otra de las iteraciones que quedan. El parámetro chunk define el número de iteraciones contiguas que se asignan a un subproceso a la vez.
guiado : se asigna una gran cantidad de iteraciones contiguas a cada subproceso de forma dinámica (como se indicó anteriormente). El tamaño del fragmento disminuye exponencialmente con cada asignación sucesiva hasta un tamaño mínimo especificado en el parámetro fragmento
Control SI
if : Esto hará que los subprocesos ejecuten la tarea en paralelo solo si se cumple una condición. De lo contrario, el bloque de código se ejecuta en serie.
Inicialización
firstprivate : los datos son privados para cada hilo, pero se inicializan utilizando el valor de la variable que usa el mismo nombre del hilo maestro.
lastprivate : los datos son privados para cada subproceso. El valor de estos datos privados se copiará a una variable global que utiliza el mismo nombre fuera de la región paralela si la iteración actual es la última iteración en el bucle paralelizado. Una variable puede ser tanto firstprivate como lastprivate .
threadprivate : los datos son globales, pero son privados en cada región paralela durante el tiempo de ejecución. La diferencia entre threadprivate y private es el alcance global asociado con threadprivate y el valor preservado en las regiones paralelas.
Copia de datos
copyin : similar a firstprivate para las variables privadas , las variables threadprivate no se inicializan, a menos que se use copyin para pasar el valor de las variables globales correspondientes. No se necesita copiar porque el valor de una variable threadprivate se mantiene durante la ejecución de todo el programa.
copyprivate : se utiliza con single para admitir la copia de valores de datos de objetos privados en un hilo (el hilo único ) a los objetos correspondientes en otros hilos del equipo.
Reducción
reducción (operador | intrínseco: lista) : la variable tiene una copia local en cada subproceso, pero los valores de las copias locales se resumirán (reducirán) en una variable compartida global. Esto es muy útil si una operación particular (especificada en el operador para esta cláusula particular) en una variable se ejecuta de forma iterativa, de modo que su valor en una iteración particular depende de su valor en una iteración anterior. Los pasos que conducen al incremento operacional se paralelizan, pero los subprocesos actualizan la variable global de una manera segura para subprocesos. Esto sería necesario para paralelizar la integración numérica de funciones y ecuaciones diferenciales , como un ejemplo común.
Otros
flush : el valor de esta variable se restaura desde el registro a la memoria para usar este valor fuera de una parte paralela
master : ejecutado únicamente por el hilo maestro (el hilo que se desprendió de todos los demás durante la ejecución de la directiva OpenMP). No hay barreras implícitas; no es necesario que otros miembros del equipo (hilos) lo alcancen.
Rutinas de ejecución a nivel de usuario
Se utiliza para modificar/verificar el número de subprocesos, detectar si el contexto de ejecución está en una región paralela, cuántos procesadores hay en el sistema actual, establecer/desestablecer bloqueos, funciones de temporización, etc.
Variables de entorno
Un método para modificar las características de ejecución de las aplicaciones OpenMP. Se utiliza para controlar la programación de iteraciones de bucles, la cantidad predeterminada de subprocesos, etc. Por ejemplo, OMP_NUM_THREADS se utiliza para especificar la cantidad de subprocesos de una aplicación.
Implementaciones
OpenMP se ha implementado en muchos compiladores comerciales. Por ejemplo, Visual C++ 2005, 2008, 2010, 2012 y 2013 lo admiten (OpenMP 2.0, en ediciones Professional, Team System, Premium y Ultimate [20] [21] [22] ), así como Intel Parallel Studio para varios procesadores. [23] Los compiladores y herramientas de Oracle Solaris Studio admiten las últimas especificaciones de OpenMP con mejoras de productividad para el sistema operativo Solaris (UltraSPARC y x86/x64) y las plataformas Linux. Los compiladores Fortran, C y C++ de The Portland Group también admiten OpenMP 2.5. GCC también ha admitido OpenMP desde la versión 4.2.
Compiladores con una implementación de OpenMP 3.0:
CCG 4.3.1
Compilador de Mercurio
Compiladores Intel Fortran y C/C++ versiones 11.0 y 11.1, Intel C/C++ y Fortran Composer XE 2011 e Intel Parallel Studio.
Compilador IBM XL [24]
La actualización 1 de Sun Studio 12 tiene una implementación completa de OpenMP 3.0 [25]
Computación multiprocesador
Varios compiladores admiten OpenMP 3.1:
CCG 4.7 [26]
Compiladores Intel Fortran y C/C++ 12.1 [27]
Compiladores IBM XL C/C++ para AIX y Linux, V13.1 [28] y compiladores IBM XL Fortran para AIX y Linux, V14.1 [29]
Allinea MAP : generador de perfiles para códigos OpenMP y MPI
TotalView: depurador de Rogue Wave Software para OpenMP, MPI y códigos seriales
ompP – generador de perfiles para OpenMP
VAMPIR – generador de perfiles para código OpenMP y MPI
Pros y contras
Ventajas:
Código multiproceso portable (en C/C++ y otros lenguajes, normalmente es necesario llamar a primitivas específicas de la plataforma para obtener multiproceso).
Simple: no es necesario lidiar con el paso de mensajes como lo hace MPI .
El diseño y la descomposición de los datos se gestionan automáticamente mediante directivas.
Escalabilidad comparable a MPI en sistemas de memoria compartida. [39]
Paralelismo incremental: puede trabajar en una parte del programa a la vez, no se necesita ningún cambio drástico en el código.
Código unificado para aplicaciones seriales y paralelas: las construcciones OpenMP se tratan como comentarios cuando se utilizan compiladores secuenciales.
En general, no es necesario modificar las instrucciones del código original (en serie) cuando se ejecutan en paralelo con OpenMP. Esto reduce la posibilidad de introducir errores inadvertidamente.
En aplicaciones multifísicas irregulares que no se adhieren únicamente al modo de cálculo SPMD , como las que se encuentran en sistemas fluido-partículas estrechamente acoplados, la flexibilidad de OpenMP puede tener una gran ventaja de rendimiento sobre MPI . [39] [40]
Se puede utilizar en varios aceleradores como GPGPU [41] y FPGA .
Contras:
Riesgo de introducir errores de sincronización y condiciones de carrera difíciles de depurar . [42] [43]
A partir de 2017, [actualizar]solo se ejecuta de manera eficiente en plataformas multiprocesador de memoria compartida (consulte Cluster OpenMP de Intel, archivado el 16 de noviembre de 2018 en Wayback Machine y otras plataformas de memoria compartida distribuida ).
Requiere un compilador que admita OpenMP.
La escalabilidad está limitada por la arquitectura de la memoria.
Carece de mecanismos detallados para controlar el mapeo entre subprocesos y procesadores.
Existe una alta probabilidad de escribir accidentalmente un código de uso compartido falso .
Expectativas de desempeño
Se podría esperar obtener una aceleración de N veces al ejecutar un programa paralelizado usando OpenMP en una plataforma de N procesadores. Sin embargo, esto rara vez ocurre por estas razones:
Cuando existe una dependencia, un proceso debe esperar hasta que se calculen los datos de los que depende.
Cuando varios procesos comparten un recurso de prueba no paralelo (como un archivo en el que escribir), sus solicitudes se ejecutan de manera secuencial. Por lo tanto, cada subproceso debe esperar hasta que el otro subproceso libere el recurso.
Una gran parte del programa no puede ser paralelizada por OpenMP, lo que significa que el límite superior teórico de aceleración está limitado según la ley de Amdahl .
N procesadores en un multiprocesamiento simétrico (SMP) pueden tener N veces más potencia de cálculo, pero el ancho de banda de memoria no suele aumentar N veces. Muy a menudo, la ruta de memoria original es compartida por varios procesadores y se puede observar una degradación del rendimiento cuando compiten por el ancho de banda de memoria compartida.
Muchos otros problemas comunes que afectan la aceleración final en la computación paralela también se aplican a OpenMP, como el equilibrio de carga y la sobrecarga de sincronización.
Es posible que la optimización del compilador no sea tan eficaz al invocar OpenMP. Esto puede provocar que un programa OpenMP de un solo subproceso se ejecute más lento que el mismo código compilado sin un indicador OpenMP (que será completamente serial).
Afinidad de hilos
Algunos proveedores recomiendan configurar la afinidad del procesador en los subprocesos OpenMP para asociarlos con núcleos de procesadores específicos. [45] [46] [47]
Esto minimiza la migración de subprocesos y el costo de cambio de contexto entre núcleos. También mejora la localidad de los datos y reduce el tráfico de coherencia de caché entre los núcleos (o procesadores).
Puntos de referencia
Se ha desarrollado una variedad de puntos de referencia para demostrar el uso de OpenMP, probar su rendimiento y evaluar su corrección.
Ejemplos sencillos
OmpSCR: Repositorio de código fuente de OpenMP
Los parámetros de rendimiento incluyen:
Punto de referencia paralelo NAS
Barcelona OpenMP Task Suite es una colección de aplicaciones que permiten probar implementaciones de tareas OpenMP.
Serie SPEC
ESPECIFICACIÓN OMP 2012
El conjunto de pruebas de referencia SPEC ACCEL que prueba la API de descarga de destino OpenMP 4
El punto de referencia SPEChpc 2002
Puntos de referencia de CORAL
Aplicaciones proxy de exaescala
Rodinia se centra en los aceleradores.
Conjunto de indicadores de referencia basados en problemas
Los parámetros de corrección incluyen:
Conjunto de validación OpenMP
Conjunto de pruebas de validación y verificación de OpenMP
DataRaceBench es un conjunto de pruebas de rendimiento diseñado para evaluar de forma sistemática y cuantitativa la eficacia de las herramientas de detección de carreras de datos OpenMP.
AutoParBench es un conjunto de pruebas de referencia para evaluar compiladores y herramientas que pueden insertar automáticamente directivas OpenMP.
^ abc "Acerca de OpenMP ARB y". OpenMP.org. 2013-07-11. Archivado desde el original el 2013-08-09 . Consultado el 2013-08-14 .
^ ab "Compiladores y herramientas de OpenMP". OpenMP.org. Noviembre de 2019. Consultado el 5 de marzo de 2020 .
^ ab Gagne, Abraham Silberschatz, Peter Baer Galvin, Greg (17 de diciembre de 2012). Conceptos de sistemas operativos (novena edición). Hoboken, Nueva Jersey: Wiley. Págs. 181-182. ISBN978-1-118-06333-0.{{cite book}}: CS1 maint: varios nombres: lista de autores ( enlace )
^ Tutorial de OpenMP en Supercomputación 2008
^ Uso de OpenMP – Programación paralela con memoria compartida portátil – Descargar ejemplos de libros y discutir
^ Costa, JJ; et al. (mayo de 2006). "Ejecución eficiente de aplicaciones OpenMP en un SDSM totalmente compartido". Journal of Parallel and Distributed Computing . 66 (5): 647–658. doi :10.1016/j.jpdc.2005.06.018. hdl : 2117/370260 .
^ Basumallik, Ayón; Min, Seung-Jai; Eigenmann, Rudolf (2007). "Programación de sistemas de memoria distribuida mediante OpenMP". 2007 Simposio internacional de procesamiento distribuido y paralelo del IEEE . Nueva York: IEEE Press. págs. 1–8. CiteSeerX 10.1.1.421.8570 . doi :10.1109/IPDPS.2007.370397. ISBN978-1-4244-0909-9. Número de identificación del sujeto 14237507.Hay una preimpresión disponible en la página de inicio de Chen Ding; consulte especialmente la Sección 3 sobre Traducción de OpenMP a MPI.
^ Wang, Jue; Hu, ChangJun; Zhang, JiLin; Li, JianJiang (mayo de 2010). "Compilador OpenMP para arquitecturas de memoria distribuida". Science China Information Sciences . 53 (5): 932–944. doi : 10.1007/s11432-010-0074-0 .(A partir de 2016, [actualizar]el software KLCoMP descrito en este documento no parece estar disponible públicamente)
^
Cluster OpenMP (un producto que solía estar disponible para las versiones 9.1 a 11.1 del compilador Intel C++ pero que se eliminó en la versión 13.0)
^ Ayguade, Eduard; Copty, Nawal; Duran, Alejandro; Hoeflinger, Jay; Lin, Yuan; Massaioli, Federico; Su, Ernesto; Unnikrishnan, Priya; Zhang, Guansong (2007). Una propuesta para el paralelismo de tareas en OpenMP (PDF) . Proc. Int'l Workshop on OpenMP.
^ "Interfaz de programación de aplicaciones OpenMP, versión 3.0" (PDF) . openmp.org. Mayo de 2008 . Consultado el 6 de febrero de 2014 .
^ LaGrone, James; Aribuki, Ayodunni; Addison, Cody; Chapman, Barbara (2011). Una implementación en tiempo de ejecución de tareas OpenMP . Proc. Int'l Workshop on OpenMP. págs. 165–178. CiteSeerX 10.1.1.221.2775 . doi :10.1007/978-3-642-21487-5_13.
^ "Lanzamiento de la API de OpenMP 4.0". OpenMP.org. 26 de julio de 2013. Archivado desde el original el 9 de noviembre de 2013. Consultado el 14 de agosto de 2013 .
^ "Interfaz de programación de aplicaciones OpenMP, versión 4.0" (PDF) . openmp.org. Julio de 2013 . Consultado el 6 de febrero de 2014 .
^ "Especificación OpenMP 5.2".
^ "OpenMP ARB publica el informe técnico 12".
^ "C - Cómo usar printf() en múltiples hilos".
^ "std::cout, std::wcout - cppreference.com".
^ "Tutorial – Bucles for paralelos con OpenMP". 14 de julio de 2009.
^ Ediciones de Visual C++, Visual Studio 2005
^ Ediciones de Visual C++, Visual Studio 2008
^ Ediciones de Visual C++, Visual Studio 2010
^ David Worthington, "Intel aborda el ciclo de vida del desarrollo con Parallel Studio", Archivado el 15 de febrero de 2012 en Wayback Machine , SDTimes, 26 de mayo de 2009 (consultado el 28 de mayo de 2009)
^ "Características de XL C/C++ para Linux" (consultado el 9 de junio de 2009)
^ "Oracle Technology Network para desarrolladores de Java | Oracle Technology Network | Oracle". Developers.sun.com . Consultado el 14 de agosto de 2013 .
^ ab "openmp – GCC Wiki". Gcc.gnu.org. 2013-07-30 . Consultado el 2013-08-14 .
^ Kennedy, Patrick (6 de septiembre de 2011). "Los compiladores Intel® C++ y Fortran ahora son compatibles con la especificación OpenMP* 3.1 | Intel® Developer Zone". Software.intel.com . Consultado el 14 de agosto de 2013 .
^ ab "Características de los compiladores IBM XL C/C++". IBM . 13 de diciembre de 2018.
^ ab "Características de los compiladores Fortran de IBM XL". 13 de diciembre de 2018.
^ ab "Notas de la versión de Clang 3.7". llvm.org . Consultado el 10 de octubre de 2015 .
^ "Página de inicio de Absoft" . Consultado el 12 de febrero de 2019 .
^ "Serie de versiones GCC 4.9 – Cambios". www.gnu.org.
^ "Características de OpenMP* 4.0 en Intel Compiler 15.0". Software.intel.com. 13 de agosto de 2014. Archivado desde el original el 16 de noviembre de 2018. Consultado el 10 de noviembre de 2014 .
^ "Serie de lanzamiento de GCC 6 - Cambios". www.gnu.org.
^ "Compiladores y herramientas de OpenMP". openmp.org . www.openmp.org . Consultado el 29 de octubre de 2019 .
^ ab "Compatibilidad con OpenMP: documentación de Clang 12". clang.llvm.org . Consultado el 23 de octubre de 2020 .
^ "GOMP — Una implementación de OpenMP para GCC - Proyecto GNU - Free Software Foundation (FSF)". gcc.gnu.org . Archivado desde el original el 2021-02-27 . Consultado el 2020-10-23 .
^ "Compatibilidad con OpenMP*". Intel . Consultado el 23 de octubre de 2020 .
^ ab Amritkar, Amit; Tafti, Danesh; Liu, Rui; Kufrin, Rick; Chapman, Barbara (2012). "Paralelismo OpenMP para sistemas fluidos y fluido-partículas". Computación paralela . 38 (9): 501. doi :10.1016/j.parco.2012.05.005.
^ Detección y prevención de condiciones de carrera de OpenMP en C++
^ "Alexey Kolosov, Evgeniy Ryzhkov, Andrey Karpov 32 trampas OpenMP para desarrolladores de C++". Archivado desde el original el 7 de julio de 2017. Consultado el 15 de abril de 2009 .
^ Stephen Blair-Chappell, Intel Corporation, Cómo convertirse en un experto en programación paralela en nueve minutos, presentación en la conferencia ACCU 2010
^ Chen, Yurong (15 de noviembre de 2007). "Software multinúcleo". Intel Technology Journal . 11 (4). doi :10.1535/itj.1104.08.
^ "Resultado OMPM2001". ESPECIFICACIÓN. 28 de enero de 2008.
^ "Resultado de la OMPM2001". ESPECIFICACIÓN. 1 de abril de 2003. Archivado desde el original el 25 de febrero de 2021. Consultado el 28 de marzo de 2008 .
Lectura adicional
Quinn Michael J, Programación paralela en C con MPI y OpenMP McGraw-Hill Inc. 2004. ISBN 0-07-058201-7
R. Chandra, R. Menon, L. Dagum, D. Kohr, D. Maydan, J. McDonald, Programación paralela en OpenMP. Morgan Kaufmann, 2000. ISBN 1-55860-671-8
R. Eigenmann (Editor), M. Voss (Editor), OpenMP Shared Memory Parallel Programming: International Workshop on OpenMP Applications and Tools, WOMPAT 2001, West Lafayette, IN, EE. UU., 30 y 31 de julio de 2001. (Lecture Notes in Computer Science). Springer 2001. ISBN 3-540-42346-X
B. Chapman, G. Jost, R. van der Pas, DJ Kuck (prólogo), Using OpenMP: Portable Shared Memory Parallel Programming. The MIT Press (31 de octubre de 2007). ISBN 0-262-53302-2
Tom Deakin y Timothy G. Mattson: Programación de su GPU con OpenMP: Portabilidad de rendimiento para GPU , The MIT Press, ISBN 978-0-262547536 (7 de noviembre de 2023).
Procesamiento paralelo mediante MPI y OpenMP, M. Firuziaan, O. Nommensen. Linux Enterprise, 10/2002
Artículo de MSDN Magazine sobre OpenMP
Tutorial de OpenMP para SC08 Archivado el 19 de marzo de 2013 en Wayback Machine (PDF) – Introducción práctica a OpenMP, Mattson y Meadows, de SC08 (Austin)
Especificaciones de OpenMP Archivado el 2 de marzo de 2021 en Wayback Machine
Miguel Hermanns: Programación paralela en Fortran 95 utilizando OpenMP (19 de abril de 2002) (PDF) (OpenMP ver.1 y ver.2)