openmp Zelfstudie
Aan de slag met openmp
Zoeken…
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.
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.
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.