openmpAan de slag met openmp


Opmerkingen

OpenMP (Open MultiProcessing) is een parallel programmeermodel gebaseerd op compilerrichtlijnen waarmee applicatieontwikkelaars incrementeel parallellisme aan hun applicatiecodes kunnen toevoegen.

OpenMP API-specificatie voor parallelle programmering biedt een applicatie-programmeerinterface (API) die multiprocessing-multiprocessing-programmering op meerdere platforms in C, C ++ en Fortran op de meeste platforms ondersteunt. Het bestaat uit een set compilerrichtlijnen, bibliotheekroutines en omgevingsvariabelen die runtime-gedrag beïnvloeden.

Omdat OpenMP zich richt op het parallellisme binnen een knooppunt (multiprocessing met gedeeld geheugen), kan het worden gecombineerd met berichtdoorvoerende programmeermodellen, zoals MPI, om op meerdere knooppunten te worden uitgevoerd.

versies

Versie Taal Publicatiedatum
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

Compilatie

Er zijn veel compilers die verschillende versies van de OpenMP-specificatie ondersteunen. OpenMP houdt hier een lijst bij met de compiler die het ondersteunt en de ondersteunde versie. Over het algemeen hoeft u voor het compileren (en koppelen) van een applicatie met OpenMP-ondersteuning alleen een compilatievlag toe te voegen en als u de OpenMP API gebruikt, moet u de OpenMP-header opnemen (omp.h). Hoewel het header-bestand een vaste naam heeft, is de compilatievlag afhankelijk van de compiler. Het volgende is een niet-limitatieve lijst met compilers en de vlag die OpenMP mogelijk maakt.

  • GCC (inclusief gcc, g ++ en gfortran): -fopenmp
  • LLVM: -fopenmp
  • Intel compiler-suite (inclusief icc, icpc en ifort): -qopenmp (en -fopenmp voor compatibiliteit met GCC / LLVM)
  • IBM XL compiler-suite (inclusief xlc, xlC en xlf): -xlsmp=omp
  • PGI compiler-suite (inclusief pgcc pgc ++ pgfortran): '-mp'

Parallelle hallo wereld met 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;
}
 

Deze code maakt eenvoudig een team threads (volgens de omgevingsvariabele OMP_NUM_THREADS - en indien niet gedefinieerd, wordt er één per logische kern op het systeem gemaakt) en elke thread identificeert zichzelf naast het afdrukken van het typische Hello world-bericht.

Reductie Voorbeeld

#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; 
    }
}
 

In de laatste regel: feitelijk toegevoegd aan een privékopie en vervolgens gecombineerd na de lus. Compiler zorgt voor de details.

Work Sharing-constructie - voorbeeld van For-lus

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

De for-lus wordt parallel uitgevoerd. huge () is een methode die te lang kan duren om uit te voeren. OpenMP ondersteunt een snelkoppeling om de bovenstaande code te schrijven als:

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

We kunnen ook een planningsbepaling hebben die beïnvloedt hoe lusherhalingen worden toegewezen aan threads. Bijvoorbeeld:

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

Verschillende stijlen van planning zijn:

schema (statisch [, stuk])
Deel blokken iteraties van grootte "brok" uit aan elke thread.
Indien niet gespecificeerd: wijs zo gelijk mogelijk toe aan de beschikbare threads

schema (dynamische [, brok])
Elke thread grijpt "brok" iteraties uit een wachtrij totdat alle iteraties zijn afgehandeld.

schema (geleide [, brok])
Draden grijpen dynamisch blokken iteraties. De grootte van het blok begint groot en krimpt naar grootte "stuk" naarmate de berekening vordert.

schema (runtime)
Schema en deelgrootte overgenomen uit de omgevingsvariabele OMP_SCHEDULE.