OpenMP je način paralelnega programiranja v načinu, ko je več proceorjev priklopljeno na skupen spomin. Glavna prednost takega programiranja je enoten naslovni prostor preko celotnega spominskega sistema
- vsak procesor lahko bere in piše na vse spominske lokacije
- eden logičen spominski prostor
- vsi procesorji naslavjlajo spomin z istim naslovom
Težave pri OpenMP so, da idealna struktura pri večjih sistemi ni mogoča in običajno obstaja naslednja oblika z hierarhičnim načinom povezave procesorjev in spomina preko hitre mreže.
Komunikacija je lahko problematična in zato je pomembno, kako se uporablja vmesni in lokalni spomin (cache).
Programiranje z deljenim spominom (shared memory) je enostavno. Pri standardizaciji se je najbolj uveljavil OpenMP, ki upravlja z nitmi na način predprocesorskih direktiv, kar napišemo kot direktivo, ki se normalno ne prevaja
Osnova vzporednega programiranja je območje parallel, ki definira področje programa.
Skupni in zasebni podatki
- Znotraj področja parallel so spremenljivke lahko deljene oz. skupne (shared) ali zasebne (private)
- Vse niti vidijo isto kopijo skupnih spremenljivk
- Vse niti lahko berejo ali pišejo v skupne spremenljivke
- Vsaka nit ima svojo kopijo zasebnih spremenljivk. Te se nevidne za druge niti
- Zasebna spremenljivka se lahko bere ali piše le v niti, ki si jo lasti
- Zasebne spremenljivke nimajo začetne vrednosti in jih je potrebno inicializirati na začetku paralelnega območja
- Skupne spremenljivke, ki jih uporabljamo le za branje lahko prosto uporabljamo v vseh paralelnih območjih
do i = 1, 100
a(i) = a(i) + b(i)
end do
Za sinhronizacijo pisanja in branja deljenih spremenljivk skrbi OpenMP. Če sinhronizacija blokira računanje niti je bolje uporabiti delno izračunavanje, ki se združi na koncu z redukcijo v eno samo spremenljivko, kar je uporabno za veliko računskih operacij. Naslednji primer je primeren za redukcijo
b = 0;
for (i=0; i++; i<N)
b += i;
Za prevajanje z OpenMP uporabimo direktivo -mp, kar je odvisno tudi od pevajalnika in jezika
- GNU Fortran: f95 -mp -o prog prog.f
- GNU C: gcc -mp -o prog prog.c
- Intel Fortran: ifort -openmp -o prog prog.f
- Intel C: icc -openmp -o prog prog.c
Gnezdenje in posvojitve
Gnezdenje zank (nesting) je dovoljeno v OpenMP kar se vključi s sistemsko spremenljivko OMP_NESTED ali klicem podprograma OMP_SET_NESTED. Če je vklopljeno, potem se bo pri vsaki direktivi PARALLEL vzpostavila nova množica niti.
Posvojitve (orphaned directives) so aktivne v dinamičnem pogledu, kar omogoča modularno programiranje s podprogrami. Primer
!$OMP PARALLEL
call fred()
!$OMP END PARALLEL
subroutine fred()
!$OMP DO
do i = 1,n
a(i) = a(i) + 23.5
end do
return
end
v katerem se podprogram fred kIiče vzporedno; vendar se zanka razdeli na niti dinamično in ne samo leksično. Podprogram fred() se je tako posvojil in vsaka nit izračunava le del deljenega polja a(i).
Druge značilnosti OpenMP
- Na nekaterih sistemih je mogoče uporabiti dinamični paralelizem, ki omogoča sistemu, da sam izbere število niti. Število niti bo enako ali manjše tistim, ki jih je nastavil uporabnik. Vkopi se z rutino OMP_SET_DYNAMIC ali sistemsko spremenljivko OMP_DYNAMIC.
- Lokalne kopije globalnih spremenljivk so včasih uporabne. Določa se jih z direktivo THREADPRIVATE.
- Stavek COPYIN prav zaprav klopira podatkeTHREADPRIVATE za posamezne niti iz glavne niti.
-
common /junk/ nx
common /stuff/ a,b,c
!$OMP THREADPRIVATE (/JUNK/,/STUFF/)
nx = 32
c = 17.9
. . .
!$OMP PARALLEL PRIVATE(NX2,CSQ) COPYIN(/JUNK/,C)
nx2 = nx * 2
csq = c*c
- Lokalne spremenljivke lahko kopiramo tudi nazaj v glavno nit z direktivo COPYPRIVATE
- Pogojno prevajanje je uporabno za pisanje programov, ki se lahko prevedejo z različnimi prevajalniki. Tudi tisitmi, ki OpenMP nimajo in lahko kodo, ki ima klicanje OpenMP podprogramov še vedno prevedemo serijsko.
- Vhod/izhod. Lahko predpostavimo, da je pisanje in branje večnitno varno. Možna pa so prepletanja niti, kar povzroča nesinhronizirano pisanje v datoteko. Ni pa možno, da vi imele posamezne niti zasebna mesta za pisanje. Možno pa je, da imajo posamezne niti zasebne datoteke v katere pišejo ali berejo.
Zmogljivost in slabosti OpenMP
Obstaja pet glavnih vzrokov za slabšo zmogljivost programov z deljenim spominom:
- sekvenčna koda
- komunikacija
- neuravnovešenost dela posameznih niti
- sinhronizacija
- slaba optimizacija s strani prevajalnika
OpenMP in MPI
V novejšem času se uporabljajo arhitekture sestavov (cluster) kar predstavlja tudi možnost za kombiniranje OpenMP in MPI.
Motivacija z skupno programiranje OpenMP in MPI je lahko v
- Prenašanje podatkov z MPI je lahko veliko
- Slabo skaliranje MPI kode
- Omejeno število MPI procesov zaradi knjižnic ali velikega števila procesov in s tem komunikacije.
- MPI implementacija ni primerna za SMP sestave