Gå til innhold

[Løst] Paralellisering og performance med OpenMP, R/W array access


Anbefalte innlegg

Hei!

 

Jeg har en løkke jeg ønsker å paralellisere med OpenMP, men akkurat nå går den signifikant langsommere når jeg kjører med flere CPU'er en ved én CPU - ikke helt ideelt.

 

Løkka løper over et array av partikkler, og oppdaterer hastighet/posisjon til hver av disse ved å se på kraften fra et elektrisk felt. Hver partikkel oppdateres in-place, og det elektriske feltet er konstant.

 

Jeg var noe bekymret over cache-miss problemer, men det er ut til at løkka deles opp slik at CPU 0 tar n=0--np/ncpus, CPU1 np/ncpus--2*np/ncpus, osv. - så overlappende cache burde bare skje i "endene" av array'et.

 

Videre er det elektriske feltet aldri oppdatert i denne funksjonen, så selv om de samme områdene av Eg_r og Eg_z brukes på de fleste partikklene, så er dette kun lesing og bør ikke lage cache-problemer.

 

Når jeg leser dokumentasjonen til OpenMP, så stresser den bruk av "#pragma omp flush(variabel,..)" i hytt og pine. Men så vidt jeg ser, så blir hver posisjon av det "beskrevne" arrayet kun brukt av én løkke - og de andre array'ene er read-only. Må jeg likevel bruke flush?

 

Er det noe annet jeg overser fullstendig her? Jeg er ikke så veldig kjent med shared-memory paralellprogrammering, og har aldri brukt OpenMP før...

 

Platform er Lin64 / GCC4 dersom dette har noe å si.

 

Funksjonen ser slik ut (np og NZ er ikke deklarert som shared, da de er const og compileren klagde når jeg forsøkte):

void  push_2D( Particle pa[], const double Eg_r[], const double Eg_z[],
	const int np, const int NZ )
{
 int	   j, k, n;
 double	hr,  Er;
 double	hz,  Ez;
 double	r0, ca, sa, vr;

#pragma omp parallel for   \
 shared(pa,Eg_r,Eg_z)	\
 private(j,k, n,hr,Er,hz,Ez,r0,ca,sa,vr)	   \
 default(none) schedule(static)
 for( n=0; n &--#60; np; n++)
   {
//Slettet koden...
pa[n] = en del matte(pa[n])
 }
}

Endret av kyrsjo
Lenke til kommentar
Videoannonse
Annonse

Hmm.. Ved nøyere sjekk, ser det ut til at walltime faktisk ikke blir værre - men CPU tid går ganske mye opp:

kyrre ~/tmp/arcpic/test $ OMP_NUM_THREADS=1 time ./ArcPIC_test > readme-1CPU.out
267.40user 1.21system 4:30.62elapsed 99%CPU (0avgtext+0avgdata 80280maxresident)k
0inputs+1314944outputs (0major+7643minor)pagefaults 0swaps
kyrre ~/tmp/arcpic/test $ OMP_NUM_THREADS=4 time ./ArcPIC_test > readme-1CPU.out
588.99user 3.52system 4:32.53elapsed 217%CPU (0avgtext+0avgdata 81116maxresident)k
0inputs+1314920outputs (0major+7341minor)pagefaults 0swaps

 

Antagelig var måten jeg tok tiden på tidligere ikke helt optimal når paralellprosessering var involvert. Men stadig så er det ingen forbedring, kun fortreiging.

 

*kjøre profiler*

Lenke til kommentar

Hmm, det der var en skikkelig leksjon i "kjør profiler FØR optimalisering". Nå er vel ikke gprof den mest fantastiske profiler'n noen sinne, men den gir definitivt en indikasjon. I dette tilfellet gav den en indikasjon om at push_2D tok en fullstendig neglisjerbar (umålbar) anndel av den totale kjøretiden, så paralellisering av denne seksjonen er fullstendig bortkastet...

 

Menmen - det var i allefall en grei leksjon i OpenMP...

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...