No haga caso de OpenMP en la máquina que no tiene que
Pregunta
Tengo un programa en C ++ usando OpenMP, que se desarrollará en varias máquinas que pueden tener o no tener instalados OpenMP.
¿Cómo pude hacer mi programa de saber si una máquina no tiene OpenMP e ignorar los #include <omp.h>
, directivas OpenMP (como #pragma omp parallel ...
) y / o funciones de biblioteca (como tid = omp_get_thread_num();
)?
Solución
OpenMP es una cosa compilador en tiempo de ejecución y no una cosa plataforma.
ie. Si compila su aplicación utilizando Visual Studio 2005 o superior, entonces uno siempre tiene OpenMP disponible como el tiempo de ejecución lo soporta. (Y si el usuario final no tiene el Estudio C instalado el tiempo de ejecución de Visual, a continuación, su aplicación no funcionará en absoluto).
Por lo tanto, usted no tiene que preocuparse, si es que se puede utilizar, siempre va a estar ahí al igual que funciones como strcmp. Para asegurarse de que tienen el CRT, entonces se puede instalar el redistribuible de Visual Studio.
editar
bien, pero GCC 4.1 no será capaz de compilar su aplicación OpenMP, por lo que el problema no es la máquina de destino, pero el compilador objetivo. macros que dan su versión que todos los compiladores han pre-definido, envuelva su OpenMP llama con #ifdef bloques. por ejemplo, GCC utiliza 3 macros para identificar la versión del compilador, __GNUC__, __GNUC_MINOR__ and __GNUC_PATCHLEVEL__
Otros consejos
OpenMP compilación añade la definición de preprocesador "_OPENMP", por lo que puede hacer:
#if defined(_OPENMP)
#pragma omp ...
#endif
En algunos ejemplos, véase http://bisqwit.iki.fi/story/ howto / OpenMP / # Discusión y el código que sigue.
Los compiladores se supone hacer caso omiso de las directivas #pragma
que no entienden; ese es el punto central de la sintaxis. Y las funciones definidas en openmp.h
tienen significados simples bien definidos en un sistema no paralelo - en particular, el archivo de cabecera comprobará si el compilador define ENABLE_OPENMP
y, si no está activado, proporciona los retrocesos derecha
Por lo tanto, todo lo que necesita es una copia de openmp.h
enlazar. Aquí hay uno: http://cms.mcc.uiuc.edu/ qmcdev / docs / html / OpenMP_8h-source.html .
La parte pertinente del código, sin embargo, es sólo esto:
#if defined(ENABLE_OPENMP)
#include <omp.h>
#else
typedef int omp_int_t;
inline omp_int_t omp_get_thread_num() { return 0;}
inline omp_int_t omp_get_max_threads() { return 1;}
#endif
En el peor, que sólo puede tomar esas tres líneas y ponerlas en un archivo openmp.h
ficticia, y usar eso. El resto se acaba de trabajar.
Hay otro enfoque que me gusta, tomado de Bisqwit :
#if defined(_OPENMP)
#include <omp.h>
extern const bool parallelism_enabled = true;
#else
extern const bool parallelism_enabled = false;
#endif
A continuación, iniciar su OpenMP paralelo para los bucles de esta manera:
#pragma omp parallel for if(parallelism_enabled)
Nota: No razones válidas para no usar pragma
, que no es estándar, por lo tanto, por las que Google y otros no lo soportan.
¿Cómo pude hacer mi programa de saber si una máquina no tiene OpenMP e ignorar los
#include <omp.h>
, directivas OpenMP (como#pragma omp parallel ...
) y / o funciones de biblioteca (comotid = omp_get_thread_num();
)?
Esto es una respuesta tardía, pero acabamos de recibir una informe de error debido al uso de #pragma omp simd
en compiladores de Microsoft.
Según OpenMP Especificación , sección 2.2:
compilación condicional
En implementaciones que apoyan un preprocesador, la macro nombre _OPENMP se define que tiene el valor decimal YYYYMM donde aaaa y mm son la onth año y las denominaciones de la versión de la API OpenMP que la implementación soporta.
Parece modernos compiladores de Microsoft sólo admiten OpenMP desde algún momento entre 2000 y 2005. Sólo puedo decir "en algún momento entre" porque OpenMP 2.0 fue lanzado en 2000, y OpenMP 2.5 fue lanzado en 2005. Sin embargo, Microsoft anuncia una versión de 2002.
Aquí están algunos números _OPENMP
...
- Visual Studio 2012 - 200203 OpenMP
- Visual Studio 2017 - 200203 OpenMP
- IBM XLC 13.01 - OpenMP 201107
- Sonido metálico 7,0 - OpenMP 201107
- GCC 4.8 - OpenMP 201107
- GCC 8.2 - OpenMP 201511
Así que si usted desea utilizar, por ejemplo #pragma omp simd
para proteger un bucle, y #pragma omp simd
está disponible en OpenMP 4.0, a continuación:
#if _OPENMP >= 201307
#pragma omp simd
for (size_t i = 0; i < 16; ++i)
data[i] += x[i];
#else
for (size_t i = 0; i < 16; ++i)
data[i] += x[i];
#endif
que se desarrollará en varias máquinas que pueden tener o no tener instalados OpenMP.
Y para que quede claro, es probable que necesite para construir su programa en cada una de esas máquinas. El x86_64 ABI no garantiza OpenMP está disponible en x86, x32 o x86_64 máquinas. Y no he leído se puede construir en una máquina, y después ejecutar en otra máquina.