openmpDémarrer avec openmp


Remarques

OpenMP (Open MultiProcessing) est un modèle de programmation parallèle basé sur des directives de compilation qui permettent aux développeurs d'applications d'ajouter parallèlement des codes d'application à leurs codes d'application.

La spécification OpenMP API pour la programmation parallèle fournit une interface de programmation d’applications (API) qui prend en charge la programmation multi-plateforme de multiprocesseur à mémoire partagée en C, C ++ et Fortran, sur la plupart des plates-formes. Il se compose d'un ensemble de directives de compilation, de routines de bibliothèque et de variables d'environnement qui influencent le comportement au moment de l'exécution.

Comme OpenMP se concentre sur le parallélisme au sein d’un nœud (multitraitement de la mémoire partagée), il peut être combiné avec des modèles de programmation de transmission de messages, tels que MPI, pour s’exécuter sur plusieurs nœuds.

Versions

Version La langue Date de sortie
4.5 C / C ++ / Fortran 2015-11-01
4.0 C / C ++ / Fortran 2013-07-01
3.1 C / C ++ / Fortran 2011-07-01
3.0 C / C ++ / Fortran 2008-05-01
2,5 C / C ++ / Fortran 2005-05-01
2.0c C / C ++ 2002-03-01
2.0f Fortran 2000-11-01
1.0c C / C ++ 1998-10-01
1.0f Fortran 1997-10-01

Compilation

De nombreux compilateurs prennent en charge différentes versions de la spécification OpenMP. OpenMP maintient une liste ici avec le compilateur qui le supporte et la version prise en charge. En général, pour compiler (et lier) une application avec le support OpenMP, il vous suffit d'ajouter un indicateur de compilation et si vous utilisez l'API OpenMP, vous devez inclure l'en-tête OpenMP (omp.h). Alors que le fichier d'en-tête a un nom fixe, l'indicateur de compilation dépend du compilateur. Voici une liste non exhaustive des compilateurs et de l'indicateur qui active OpenMP.

  • GCC (y compris gcc, g ++ et gfortran): -fopenmp
  • LLVM: -fopenmp
  • Suite de compilateur Intel (incluant icc, icpc et ifort): -qopenmp (et -fopenmp pour la compatibilité avec GCC / LLVM)
  • Suite de compilateur IBM XL (y compris xlc, xlC et xlf): -xlsmp=omp
  • Suite de compilation PGI (incluant pgcc pgc ++ pgfortran): '-mp'

Bonjour tout le monde en utilisant OpenMP

#include <omp.h>
#include <stdio.h>

int main (int argc, char *argv[])
{
   #pragma omp parallel
   {
     printf ("Hello world! I'm thread %d out of %d threads.\n",
             omp_get_thread_num(), omp_get_num_threads());
   }
   return 0;
}
 

Ce code crée simplement une équipe de threads (selon la variable d'environnement OMP_NUM_THREADS - et s'il n'est pas défini en créera un par coeur logique sur le système) et chaque thread s'identifiera en plus d'imprimer le message Hello World typique.

Exemple de réduction

#include <omp.h>
void main ()
{     
    int i;       
    double ZZ, func(), res=0.0;

    #pragma omp parallel for reduction(+:res) private(ZZ) 
    for (i=0; i< 1000; i++){
        ZZ = func(I);
        res = res + ZZ; 
    }
}
 

Dans la dernière ligne: En fait ajouté à une copie privée, puis combiné après la boucle. Le compilateur prend en charge les détails.

Construction de partage de travail - Exemple de boucle For

double  res[MAX];  int i;
#pragma omp parallel 
{    
    #pragma omp for
    for (i=0;i< MAX; i++) {
        res[i] = huge();
    } 
}    
 

La boucle for sera exécutée en parallèle. huge () est une méthode qui peut prendre trop de temps pour s'exécuter. OpenMP prend en charge un raccourci pour écrire le code ci-dessus en tant que:

double  res[MAX];  int i;
#pragma omp parallel for
for (i=0;i< MAX; i++) {
    res[i] = huge();
} 
 

Nous pouvons également avoir une clause Schedule qui affecte la façon dont les itérations de la boucle sont mappées aux threads. Par exemple:

#pragma omp parallel
#pragma omp for schedule(static)
for(i=0;I<N;i++) {
    a[i] = a[i] + b[i];
}
 

Différents styles de planification sont:

calendrier (statique [, morceau])
Dégagez des blocs d'itérations de taille «chunk» à chaque thread.
Si non spécifié: allouer aussi uniformément que possible aux threads disponibles

calendrier (dynamique [, morceau])
Chaque thread récupère des itérations «en bloc» dans une file d'attente jusqu'à ce que toutes les itérations aient été traitées.

calendrier (guidé [, morceau])
Les threads saisissent dynamiquement des blocs d'itérations. La taille du bloc commence grande et se réduit à la taille «morceau» au fur et à mesure du calcul.

planning (runtime)
Planification et taille de bloc extraite de la variable d'environnement OMP_SCHEDULE.