Domanda

Ho un programma C ++ usando OpenMP, che si svolgerà su più macchine che possono avere o non avete installato OpenMP.

Come potrei fare il mio programma di sapere se una macchina non ha OpenMP e ignorare quelli #include <omp.h>, direttive OpenMP (come #pragma omp parallel ...) e / o funzioni di libreria (come tid = omp_get_thread_num();)?

È stato utile?

Soluzione

OpenMP è una cosa compilatore runtime e non una cosa piattaforma.

es. Se si compila la vostra applicazione utilizzando Visual Studio 2005 o superiore, allora si ha sempre OpenMP disponibile come il runtime supporta. (E se l'utente finale non ha il runtime di Visual Studio C installato, allora la vostra applicazione non funzionerà affatto).

Quindi, non c'è bisogno di preoccuparsi, se è possibile utilizzarlo, sarà sempre lì, proprio come funzioni quali strcmp. Per assicurarsi che essi hanno il CRT, è possibile installare lo studio ridistribuibile visivo.

modifica:

ok, ma GCC 4.1 non sarà in grado di compilare l'openMP app, in modo che il problema non è la macchina di destinazione, ma il compilatore di destinazione. macro che danno la loro versione, come tutti i compilatori hanno pre-definito, avvolgere il vostro OpenMP chiamate con #ifdef blocchi. per esempio, GCC utilizza 3 macro per identificare la versione del compilatore, __GNUC__, __GNUC_MINOR__ and __GNUC_PATCHLEVEL__

Altri suggerimenti

compilation OpenMP aggiunge la definizione di preprocessore "_OPENMP", in modo da poter fare:

#if defined(_OPENMP)
   #pragma omp ...
#endif

Per alcuni esempi, vedere http://bisqwit.iki.fi/story/ howto / OpenMP / # Discussione e il codice che segue.

I compilatori sono tenuti a ignorare le direttive #pragma che non capiscono; questo è il punto di tutta la sintassi. E le funzioni definite in openmp.h hanno semplici significati ben definiti su un sistema non in parallelo - in particolare, il file di intestazione controllerà per se il compilatore definisce ENABLE_OPENMP e, se non è abilitata, fornire le ricadute destra

.

Quindi, tutto ciò che serve è una copia di openmp.h a cui collegarsi. Eccone uno: http://cms.mcc.uiuc.edu/ qmcdev / docs / html / OpenMP_8h-source.html .

La parte rilevante del codice, però, è proprio questo:

#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

Nel peggiore dei casi, si può semplicemente prendere quelle tre righe e metterli in un file openmp.h fittizio, e usare quella. Il resto sarà solo di lavoro.

C'è un altro approccio che mi piace, preso in prestito da Bisqwit :

#if defined(_OPENMP)
#include <omp.h>
extern const bool parallelism_enabled = true;
#else
extern const bool parallelism_enabled = false;
#endif

Quindi, avviare l'OpenMP parallelo per i loop come questo:

#pragma omp parallel for if(parallelism_enabled)

Nota: ci sono validi motivi per non usare pragma, che è non standard, quindi, perché Google e gli altri non lo supportano.

  

Come potrei fare il mio programma di sapere se una macchina non ha OpenMP e ignorare quelli #include <omp.h>, direttive OpenMP (come #pragma omp parallel ...) e / o funzioni di libreria (come tid = omp_get_thread_num();)?

Ecco una risposta in ritardo, ma abbiamo appena ricevuto una bug report causa di un uso di #pragma omp simd sui compilatori Microsoft.

OpenMP Specification , sezione 2.2:

  

Compilazione Condizionale

     

In implementazioni che supportano un preprocessore, il _OPENMP macro nome   è definito per avere il valore decimale AAAAMM dove aaaa e mm sono i   anno e ese designazioni della versione delle API OpenMP che la   implementazione supporta.

Sembra moderni compilatori Microsoft supportano solo OpenMP da qualche tempo tra il 2000 e il 2005. Posso solo dire "a volte tra il" perché OpenMP 2.0 è stato rilasciato nel 2000, ed OpenMP 2.5 è stato rilasciato nel 2005. Ma Microsoft pubblicizza una versione a partire dal 2002.

Ecco alcuni numeri _OPENMP ...

  • Visual Studio 2012 - OpenMP 200203
  • Visual Studio 2017 - OpenMP 200203
  • IBM XLC 13.01 - OpenMP 201107
  • Clang 7.0 - OpenMP 201107
  • GCC 4.8 - OpenMP 201107
  • GCC 8.2 - OpenMP 201.511

Quindi, se si desidera utilizzare, ad esempio #pragma omp simd per custodire un ciclo, e #pragma omp simd è disponibile in OpenMP 4.0, quindi:

#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

  

, che verrà eseguito su diverse macchine che possono avere o non avete installato OpenMP.

E per essere chiari, probabilmente è necessario per costruire il tuo programma su ciascuna di quelle macchine. Il x86_64 ABI non garantisce OpenMP è disponibile su x86, x32 o x86_64 macchinari. E io non ho letto si può costruire su una macchina, e quindi eseguire su un'altra macchina.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top