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();)?

¿Fue útil?

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 (como tid = 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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top