Question

J'ai un programme C ++ en utilisant OpenMP, qui se déroulera sur plusieurs machines qui peuvent avoir ou non OpenMP installés.

Comment pourrais-je faire mon programme savoir si une machine n'a pas OpenMP et ignorer les #include <omp.h>, les directives OpenMP (comme #pragma omp parallel ...) et / ou des fonctions de bibliothèque (comme tid = omp_get_thread_num();)?

Était-ce utile?

La solution

OpenMP est une chose d'exécution du compilateur et non une chose de plate-forme.

à savoir

. Si vous compilez votre application en utilisant Visual Studio 2005 ou plus, alors vous avez toujours OpenMP disponible le moteur d'exécution supporte. (Et si l'utilisateur final n'a pas le temps d'exécution de Visual Studio C installé, votre application ne fonctionnera pas du tout).

Alors, vous ne devez pas vous inquiéter, si vous pouvez l'utiliser, il sera toujours là comme des fonctions telles que strcmp. Pour vous assurer qu'ils ont le CRT, vous pouvez installer le redistribuable studio visuel.

edit:

ok, mais GCC 4.1 ne sera pas en mesure de compiler votre application OpenMP, la question est donc pas la machine cible, mais le compilateur cible. Comme tous les compilateurs ont des macros prédéfinies donnant leur version, enveloppez votre OpenMP appelle avec #ifdef blocs. par exemple, GCC utilise 3 macros pour identifier la version du compilateur, __GNUC__, __GNUC_MINOR__ and __GNUC_PATCHLEVEL__

Autres conseils

compilation OpenMP ajoute la définition de préprocesseur "_OPENMP", de sorte que vous pouvez faire:

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

Pour quelques exemples, voir http://bisqwit.iki.fi/story/ howto / OpenMP / # Discussion et le code qui suit.

sont censés Compilateurs ignorer les directives de #pragma qu'ils ne comprennent pas; c'est le point entier de la syntaxe. Et les fonctions définies dans openmp.h ont de simples significations bien définies sur un système non-parallèle - en particulier, le fichier d'en-tête va vérifier si le compilateur définit ENABLE_OPENMP et, si elle est pas activé, fournir les bonnes solutions de repli

.

Alors, tout ce que vous avez besoin est une copie de openmp.h lien. Voici une: http://cms.mcc.uiuc.edu/ qmcdev / docs / html / OpenMP_8h-source.html .

La partie pertinente du code, cependant, est ceci:

#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

Au pire, vous pouvez simplement prendre ces trois lignes et les mettre dans un fichier openmp.h factice, et l'utiliser. Le reste sera simplement travailler.

Il y a une autre approche qui me plaît, empruntée à Bisqwit :

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

Ensuite, démarrez votre parallèle OpenMP pour les boucles comme ceci:

#pragma omp parallel for if(parallelism_enabled)

Note: il y a raisons valables pour ne pas utiliser pragma, qui est non-standard, donc pourquoi Google et d'autres ne le supportent pas.

  

Comment pourrais-je faire mon programme savoir si une machine n'a pas OpenMP et ignorer les #include <omp.h>, les directives OpenMP (comme #pragma omp parallel ...) et / ou des fonctions de bibliothèque (comme tid = omp_get_thread_num();)?

Voici une réponse tardive, mais nous venons de recevoir un rapport de bogue en raison de l'utilisation de #pragma omp simd sur compilateurs Microsoft.

Selon OpenMP Spécification , section 2.2:

  

Compilation conditionnelle

     

Dans les implémentations qui prennent en charge un préprocesseur, le nom de la macro _OPENMP   est définie pour avoir le YYYYMM de valeur décimale et où aaaa mm sont la   désignations année et ois de la version de l'API OpenMP que la   soutient la mise en œuvre.

Il semble compilateurs Microsoft modernes prennent en charge que OpenMP de quelque temps entre 2000 et 2005. Je ne peux que dire « quelque part entre » parce OpenMP 2.0 a été publié en 2000, et OpenMP 2.5 a été publié en 2005. Mais Microsoft annonce une version de 2002.

Voici quelques numéros _OPENMP ...

  • Visual Studio 2012 - OpenMP 200203
  • Visual Studio 2017 - OpenMP 200203
  • IBM 13,01 XLC - OpenMP 201107
  • Clang 7.0 - OpenMP 201107
  • GCC 4.8 - OpenMP 201107
  • GCC 8.2 - OpenMP 201511

Donc, si vous voulez utiliser, par exemple #pragma omp simd pour garder une boucle, et #pragma omp simd est disponible en OpenMP 4.0, puis:

#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

  

qui se déroulera sur plusieurs machines qui peuvent avoir ou non OpenMP installés.

Et pour être clair, vous avez probablement besoin de construire votre programme sur chacune de ces machines. x86_64 ABI ne garantit pas OpenMP est disponible sur x86, machines x32 ou x86_64. Et je l'ai pas lu, vous pouvez construire sur une machine, puis exécutez sur une autre machine.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top