• Aucun résultat trouvé

Introduction à la programmation parallèle

N/A
N/A
Protected

Academic year: 2022

Partager "Introduction à la programmation parallèle"

Copied!
60
0
0

Texte intégral

(1)

Programme de formation en G´enie Par Simulation

Introduction ` a la programmation parall` ele

Avec OpenMP et MPI

Guillaume Emond

Polytechnique Montr´eal Montr´eal, QC

Novembre 2016

(2)

Table des mati` eres

1 Programmation parall`ele

2 OpenMP Directives Clauses

Concurrences et synchronisation

3 MPI

Messages

Communications collectives

(3)

Table des mati` eres

1 Programmation parall`ele

2 OpenMP Directives Clauses

Concurrences et synchronisation

3 MPI

Messages

Communications collectives

4 Conclusion

(4)

Loi d’Amdahl

La loi d’Amdahl permet de calculer l’acc´el´eration th´eorique(A), obtenu en parall´elisant un programme s´equentiel, selon le nombre de processeurs (n) utilis´es et la fraction parall´elisable du code(p).

A= 1

(1−p) +p/n (1)

Il s’agit toujours d’une borne sup´erieur de l’acc´el´eration r´eelle.

(5)

API de parall´ elisation

3 niveaux de parall´ elisation

Thread : PThread,PTh,TBB, openMP

Processus : MPI, PVM, LINDA

GPU : Cuda, openCL

Pourquoi openMP ou MPI ?

OpenMP et MPI sont simples d’utilisation

Ce sont les api les plus r´ependus dans le monde scientifique

Gratuits et portables

(6)

Processus

Un processus est un programme en cours d’ex´ecution qui est constitu´e de :

un num´ero d’identification

un espace d’adressage

un ´etat (´Elu, Prˆet, Bloqu´e)

une priorit´e

une liste d’instructions (Compteur Ordinal)

descripteurs de fichier FigureEspace d’adressage d’un

(7)

Thread

Un mˆeme processus a la possibilit´e d’avoir plus d’un fil d’ex´ecution (stack).

Ces fils d’ex´ecution partagent les ressources du processus.

Chaque thread poss`ede :

un identificateur

sa pile d’ex´ecution

son compteur ordinal

un ´etat

Figure Multithreaded process

(8)

Avantages threads vs processus

Le partage des ressources entre threads est beaucoup plus facile et efficace que pour les processus.

Probl`emes de concurrence des ressources.

La cr´eation et les changements de contexte entre threads est beaucoup plus rapide.

Les threads ne s’appliquent pas aux architectures `a m´emoire distribu´ee.

(9)

Table des mati` eres

1 Programmation parall`ele

2 OpenMP Directives Clauses

Concurrences et synchronisation

3 MPI

Messages

Communications collectives

4 Conclusion

(10)

Open Multi-Processing

Programmation en m´emoire partag´ee

API C,C++ et Fortran.

Disponible sur Linux, Unix, Mac OS X, Microsoft Windows et Solaris (www.openmp.org)

Permet de progressivement parall´eliser un programme s´equentiel sans restructurer l’enti`eret´e du programme.

(11)

Quelques mod` eles

Mod` ele d’´ execution

”Fork-Join”

Open mp consiste `a ins´erer des blocs parall`eles dans un

programme s´equentiel.

Possibilit´e d’avoir des r´egions parall`eles imbriqu´ees.

Mod` ele de m´ emoire

Variables partag´ees.

Variables priv´ees.

(12)

Syntaxe

C/C++ : #pragma omp directive [clause]

Fortran : !$OMP DIRECTIVE [CLAUSE]

: !$OMP END DIRECTIVE [CLAUSE]

Directives : parallel, for (parallel for), sections (parallel sections), single, critical, atomic, master, target, simd...

Clauses : shared, private, firstprivate, lasprivate, default, reduction, copyin, if, ordered, schedule, nowait, safelen, linear, aligned, collasped, device, map...

Les clauses disponibles pour chaque directive peuvent changer.

(13)

Fonctions de support : threads

omp (set/get) num threads : sp´ecifie/retourne le nombre de threads.

omp get max threads : retourne le nombre maximal possible de threads.

omp get thread num : retourne le num´ero du thread courant.

omp get num proc : retourne le nombre de processeurs disponibles.

omp in parallel : pour savoir si on se trouve dans une r´egion parall`ele.

omp get wtime : temps ´ecoul´e en secondes par thread.

omp get wtick : temps ´ecoul´e en cycle d’horloge par thread.

(14)

Fonctions de support : threads

omp (set/get) nested : permission d’avoir des r´egions parall`eles imbriqu´ees.

omp (set/get) set max active levels : profondeur maximale d’imbrication

omp get active level : retourne la profondeur courante de la r´egion parall`ele imbriqu´ee.

omp stacksize : retourne la taille des piles pour les threads.

(15)

Table des mati` eres

1 Programmation parall`ele

2 OpenMP Directives Clauses

Concurrences et synchronisation

3 MPI

Messages

Communications collectives

4 Conclusion

(16)

Parallel

Cr´eation des fils d’ex´ecution au d´ebut de la section parall`ele.

Le nombre de threads cr´e´es est g´en´eralement sp´ecifi´e dans la variable d’environnementOMP NUM THREAD ou par d´efault (2 x core).

Il y a une synchronisation `a la fin de la section.

Chaque thread ex´ecute les instructions dans le bloc parall`ele mais agit diff´erement selon son identificateur.

(17)

Exemple : Parallel

// H e l l o W o r l d p a r a l l e l

# i n c l u d e < s t d i o . h >

# i n c l u d e < omp . h >

int m a i n( int argc, c h a r **a r g v ) {

#p r a g m a omp p a r a l l e l {

int r a n k= o m p _ g e t _ t h r e a d _ n u m() ; int s i z e= o m p _ g e t _ n u m _ t h r e a d s() ;

p r i n t f( " H e l l o w o r l d ! I ’ m % d of % d \ n ",rank, s i z e ) ; }

r e t u r n 0;

}

export OMP NUM THREADS=4 gcc –fopenmp -o HelloWorld HelloWorld.c ./HelloWorld

Hello world ! I’m 0 of 4 Hello world ! I’m 1 of 4 Hello world ! I’m 3 of 4 Hello world ! I’m 2 of 4

(18)

For

Parall´elisation d’une boucle for (si chaque it´eration est ind´ependante des autres).

Doit ˆetre appel´e depuis un environnement parall`ele ou avec omp parallel for.

Chaque thread s’occupe d’un sous-intervalle de la boucle.

Plusieurs types de division des sous-domaines possibles : static, dynamic, guided ou auto.

(19)

Exemple : for

// f o n c t i o n e f f e c t u a n t la m o y e n n e de c h a q u e e l e m e n t s a v e c s e s v o i s i n s d i r e c t e s // o u t p u t [ 1 . . . n ]

// i n p u t [ 0 . . . n ]

int p a r a l l e l A v e r a g e(d o u b l e* output, c o n s t d o u b l e* input, c o n s t int l e n g t h) {

#p r a g m a omp p a r a l l e l for

for (int i=1; i<length-1; i++) {

o u t p u t[i-1] = (i n p u t[i-1] + i n p u t[i] + i n p u t[i+ 1 ] ) /3;

} r e t u r n 0;

}

(20)

Single et Sections

Single permet d’encapsuler un bloc d’instructions qui ne sera ex´ecut´e que par un seul thread.

Sections permet de s´eparer des tˆaches diff´erentes et de les ex´ecuter respectivement par 1 seul fil d’ex´ecution.

Le thread qui ex´ecutera une section ou le single est al´eatoire.

La directive master permet de faire un single en garantissant que le bloc sera ex´ecut´e par le thread parent (id=0).

(21)

Exemple :Single et Sections

Sections

# p r a g m a omp p a r a l l e l { f u n c t i o n _ 0() ;

#p r a g m a omp s e c t i o n s{ f u n c t i o n _ 1() ;

#p r a g m a omp s e c t i o n{ f u n c t i o n _ 2() ; }

#p r g m a omp s e c t i o n{

f u n c t i o n _ 3() ; f u n c t i o n _ 4() ; }

} }

Single

# p r a g m a omp p a r a l l e l {

#p r a g m a omp for /* b l o c p a r a l l e l 1 */

#p r a g m a omp s i n g l e{

/* b l o c s e q u e n t i e l */

}

/* b l o c p a r a l l e l 2 */

}

(22)

Autres directives

omp task

omp taskloop

omp taskloop simd

omp simd / declare simd

omp target / declare target

omp teams

etc...

(23)

Table des mati` eres

1 Programmation parall`ele

2 OpenMP Directives Clauses

Concurrences et synchronisation

3 MPI

Messages

Communications collectives

4 Conclusion

(24)

shared, private...

La port´ee des variables doit ˆetre d´efinie pour chaque r´egion parall`ele.

shared : une seule copie de la variable pour tous les threads.

private : chaque thread poss`ede une copie de la variable. La variable vis´ee est ind´efinie avant et apr`es la r´egion.

firstprivate : variable priv´ee initialis´ee avec la valeur en entr´ee.

lastprivate : la valeur de sortie est donn´ee par le thread qui effectue la derni`ere it´eration de la boucle.

copyprivate : permet de propager une variable d’une r´egion single aux autres threads

(25)

shared, private

// P r o d u i t M a t r i c e - v e c t e u r

# p r a g m a omp p a r a l l e l for d e f a u l t( n o n e ) p r i v a t e ( i , j , sum ) s h a r e d ( m , n , a , b , c ) for (i=0; i<m; i++) {

sum = 0 . 0 ;

for (j=0; j<n; j++)

sum += b[i][j]*c[j];

a[i] = sum;

}

(26)

reduction

Pour les boucles for.

Permet de sp´ecifier une variable pour une r´eduction avec un op´erateur commutatif et associatif.

+,∗,&&,k,

// f a i r e u n e s o m m e d e s e l e m e n t s d ’ un v e c t e u r .

d o u b l e s o m m e(d o u b l e* a, int s i z e) { int i;

d o u b l e sum =0;

#p r a g m a omp p a r a l l e l for p r i v a t e(i) r e d u c t i o n(+:sum)

for(i=0; i<s i z e; i++) {

sum += a[i];

}

r e t u r n sum;

}

(27)

collapse

Dans un omp for, seule la premi`ere boucle est parall´elis´ee.

Avec la clause collapse, des boucles imbriqu´ees seront consid´er´ees comme une grande boucle.

// f a i r e u n e s o m m e d e s e l e m e n t s d ’ u n e m a t r i c e d o u b l e s o m m e(d o u b l e* a, int width, int h e i g h t) {

int i,j;

d o u b l e sum =0;

#p r a g m a omp p a r a l l e l for p r i v a t e(i,j) c o l l a p s e(2) r e d u c t i o n(+:sum) for(i=0; i<s i z e; i++) {

for(j=0; j<s i z e; j++)

sum += a[i][j];

}

r e t u r n sum;

}

(28)

if

Le bloc parall`ele attach´e au if ne s’ex´ecute que si la condition est vraie.

Dans le cas contraire, la r´egion s’ex´ecute en s´equentiel.

Si la taille du probl`eme est petite, il est parfois pr´ef´erable de rester en s´equentiel `a cause du surcoˆut de opemMP.

(29)

nowait

Permet d’enlever la barri`ere implicite `a la fin d’un bloc. Ainsi l’ex´ecution de deux r´egions parall`eles distinctes peuvent se chevaucher.

La directive omp barrier permet de synchroniser tous les threads de la r´egion.

# p r a g m a p a r a l l e l s h a r e d ( a , b , c , y , z ) { #p r a g m a omp for s c h e d u l e(s t a t i c) n o w a i t

for (int i=0; i<n; i++) c[i] = (a[i] + b[i]) / 2 . 0 ;

# p r a g m a omp for s c h e d u l e (s t a t i c) n o w a i t

for (int i=0; i<n; i++) z[i] = c[i]*c[i];

# p r a g m a omp b a r r i e r ;

# p r a g m a omp for s c h e d u l e (s t a t i c) n o w a i t

for (int i=1; i<=n; i++) y[i] = z[i-1] + a[i];

}

(30)

Table des mati` eres

1 Programmation parall`ele

2 OpenMP Directives Clauses

Concurrences et synchronisation

3 MPI

Messages

Communications collectives

(31)

Probl` eme ? ? ?

# i n c l u d e < s t d i o . h >

# i n c l u d e < omp . h >

int m a i n( int argc, c h a r **a r g v ) { int N = 1 0 0 ;

d o u b l e a[N];

d o u b l e t o t a l = 0;

for(int i=0; i<N; i++) a[i]=i;

#p r a g m a omp p a r a l l e l n u m _ t h r e a d s(4) {

#p r a g m a omp for for(int i=0; i<N; i++) {

t o t a l += a[i]

} } r e t u r n t o t a l;

}

eponse actuelle : 3745 eponse attendue : 4950

(32)

critical et atomic

Afin de r´egler un probl`eme de concurrence, Il faut que l’acc`es aux donn´ees cibl´ees soit prot´eg´e soit par des verrous ou en ´etant locales.

#pragma omp critical [name] : Une seule r´egion critique du mˆeme nom peut s’ex´ecuter en mˆeme temps. Cette directive utilise des verrous afin de prot´eger la r´egion.

#pragma omp atomic{x operateur= expression}

# p r a g m a omp p a r a l l e l n u m _ t h r e a d s (4) { int i,j;

#p r a g m a omp for for(i=0; i<N; i++) {

#p r a g m a omp c r i t i a l{

t o t a l += a[i]

} } }

# p r a g m a omp p a r a l l e l n u m _ t h r e a d s (4) { int i,j;

#p r a g m a omp for for(i=0; i<N; i++) {

#p r a g m a omp a t o m i c{

t o t a l += a[i]

}

(33)

Quelques conseils

Attention aux probl`emes de concurrence. S’assurer que les fonctions appel´ees sont ”thread safe”

Choisir des morceaux assez gros pour minimiser le surcoˆut mais assez petits pour ´equilibrer le travail de chaque thread.

Attention `a l’odre des indices lors du parcours de matrice.

(34)

Table des mati` eres

1 Programmation parall`ele

2 OpenMP Directives Clauses

Concurrences et synchronisation

3 MPI

Messages

Communications collectives

(35)

Message Passing Interface

Ce n’est pas une librairie mais un standard. Il exite plusieurs impl´ementations diff´erentes (openMPI, MPICH, MVAPICH, IBM MPI, etc...)

Habituellement support´e en C,C++ et Fortran et sur la plupart des syst`emes d’exploitations.

Programmation sur architechture `a m´emoire distribu´ee.

Un programme MPI est constitu´e de processus autonomes qui ex´ecutent leur code respectif (MIMD) dans leur espace d’adressage respectif. MPI est un environnment servant uniquement `a la communication entre ces processus.

(36)

Syntaxe

C/C++ : ierr = MPI Xxxx(parametre1, ...)

ierr = MPI Bsend(&buf,count,type,dest,tag,comm) Fortran : MPI XXXX(parametre1, ..., ierr)

MPI BSEND(&buf,count,type,dest,tag,comm,ierr)

(37)

Fonctions de base

MPI INIT : initialisation de l’environnment MPI. Il ne doit ˆetre appel´e qu’une seule fois dans le programme.

MPI FINALIZE : terminaison des communications.

MPI COMM RANK : retourne le num´ero du processus.

MPI COMM SIZE : retourne le nombre de processus dans le communicateur (MPI COMM WORLD).

MPI ABORD : terminaison de tous les processus MPI.

(38)

Hello World MPI

mpiexec ./HelloWorldMPI.c -np 4

# i n c l u d e " mpi . h "

# i n c l u d e < s t d i o . h >

int m a i n( argc, a r g v ) { int rank, s i z e;

M P I _ I n i t( &argc, &a r g v ) ;

M P I _ C o m m _ r a n k( M P I _ C O M M _ W O R L D, &r a n k ) ; M P I _ C o m m _ s i z e( M P I _ C O M M _ W O R L D, &s i z e ) ;

p r i n t f( " H e l l o w o r l d ! I ’ m % d of % d \ n ",rank, s i z e ) ; M P I _ F i n a l i z e() ;

r e t u r n 0;

}

Hello world ! I’m 3 of 4 Hello world ! I’m 2 of 4 Hello world ! I’m 0 of 4

(39)

Table des mati` eres

1 Programmation parall`ele

2 OpenMP Directives Clauses

Concurrences et synchronisation

3 MPI

Messages

Communications collectives

4 Conclusion

(40)

Contenu d’un message Le contenu

buffer : adresse de la variable qui est envoy´ee ou qui recevra les donn´ees.

count : nombre d’´el´ements dans le buffer

datatype : type de la donn´ee pass´ee dans le message. Il ne peut y en avoir qu’un seul par message. Le syst`eme peut effectuer des

conversions si n´ecessaire.

L’enveloppe

source : L’identificateur de l’envoyeur.

dest : L’identificateur du receveur.

tag : Valeur enti`ere identifiant le message (possibilit´e de wildcard `a la r´eception : MPI ANY TAG).

(41)

Exemple de communication

# i n c l u d e " mpi . h "

int m a i n( int argc, c h a r *a r g v[]) {

c h a r m e s s a g e[ 2 0 ] ; int m y r a n k;

M P I _ S t a t u s s t a t u s;

M P I _ I n i t( &argc, &a r g v ) ;

M P I _ C o m m _ r a n k( M P I _ C O M M _ W O R L D, &m y r a n k ) ; if (m y r a n k == 0) { /* c o d e f o r p r o c e s s z e r o */

s t r c p y(message," Hello , t h e r e ") ;

M P I _ S e n d(message, s t r l e n(m e s s a g e) , M P I _ C H A R, 1 , 99 , M P I _ C O M M _ W O R L D) ; }

e l s e if (m y r a n k == 1) { /* c o d e f o r p r o c e s s o n e */

M P I _ R e c v(message, 20 , M P I _ C H A R, 0 , 99 , M P I _ C O M M _ W O R L D, &s t a t u s) ; p r i n t f(" r e c e i v e d :% s :\ n ", m e s s a g e) ;

}

M P I _ F i n a l i z e() ; r e t u r n 0;

}

(42)

Mode de communication

Standard, Buffered, Synchronous, Ready

MPI XSEND(buf,count,datatype,dest,tag,comm)

1. MPI SEND : peut se comporter comme un BSEND ou SSEND selon le choix de MPI.

2. MPI BSEND : termine lorsque le message est compl`etement copi´e dans un tampon.

3. MPI SSEND : termine lorsqu’un RECV correspondant est appel´e.

4. MPI RSEND : ne peut ˆetre appel´e que si un RECV correspondant est en attente.

MPI RECV(buf,count,datatype,source,tag,comm,status)

Termine lorsque le message est totalement copi´e. Un RECV peut terminer avant le SEND.

(43)

interblocage

// E X E M P L E 1

M P I _ C o m m _ r a n k(comm, &r a n k) if (r a n k= = 0 ) {

M P I _ B s e n d(sendbuf, count, M P I _ D O U B L E, 1 , tag1, c o m m) M P I _ S s e n d(sendbuf, count, M P I _ D O U B L E, 1 , tag2, c o m m) }

e l s e i f (r a n k= = 1 ) {

M P I _ R e c v(recvbuf, count, M P I _ D O U B L E, 0 , tag2, comm, s t a t u s) M P I _ R e c v(recvbuf, count, M P I _ D O U B L E, 0 , tag1, comm, s t a t u s) }

// E X E M P L E 2

M P I _ C o m m _ r a n k(comm, &r a n k) if (r a n k= = 0 ) {

M P I _ S e n d(sendbuf, count, M P I _ R E A L, 1 , tag, c o m m) M P I _ R e c v(recvbuf, count, M P I _ R E A L, 1 , tag, comm, s t a t u s) }

e l s e i f (r a n k= = 1 ) {

M P I _ S e n d(sendbuf, count, M P I _ R E A L, 0 , tag, c o m m) M P I _ R e c v(recvbuf, count, M P I _ R E A L, 0 , tag, comm, s t a t u s) }

(44)

SendReceive

On combine les appels send et receive afin de simplifier les ´echanges de message.Cela ´evite les risque d’interblocages.

MPI SENDRECV(sendbuf,sendcount,sendtype,dest,sendtag, recvbuf,recvcount,recvtype,source,recvtag,comm,status)

MPI SENDRECV REPLACE(buf,count,datatype,dest,sendtag, source,recvtag,comm,status)

(45)

Exemple : SendRecv

intrank,s i z e;

M P I _ s t a t u s s t a t u s;

f l o a t r p[2048] ,rs[2048] ,rc[ 2 0 4 8 ] ; ...

for(t=0;t<m a x _ t i m e;t++) { if(r a n k < (size-1) {

M P I _ S e n d r e c v(rc,2048 ,M P I _ F L O A T,r a n k+1 ,1 ,rs,2048 ,M P I _ F L O A T,r a n k+1 ,0 ,M P I _ C O M M _ W O R L D) ; }

if(r a n k > 0) {

M P I _ S e n d r e c v(rc,2048 ,M P I _ F L O A T,rank-1 ,0 ,rp,2048 ,M P I _ F L O A T,rank-1 ,1 ,M P I _ C O M M _ W O R L D) ; }

i t e r e _ c h a l e u r(rp,rs,rc) }

(46)

Exemple : SendRecv

intrank,s i z e;

M P I _ s t a t u s s t a t u s;

f l o a t rp[2048] ,rs[2048] ,rc[ 2 0 4 8 ] ; ...

for(t=0;t<m a x _ t i m e;t++) { if(r a n k= = 0 ) {

M P I _ S e n d r e c v(rc,2048 ,M P I _ F L O A T,r a n k+1 ,1 ,rs,2048 ,M P I _ F L O A T,r a n k+1 ,0 ,M P I _ C O M M _ W O R L D) ; i t e r e _ c h a l e u r(NULL,rs,rc)

}

e l s e i f(r a n k==(size-1) ) {

M P I _ S e n d r e c v(rc,2048 ,M P I _ F L O A T,rank-1 ,0 ,rp,2048 ,M P I _ F L O A T,rank-1 ,1 ,M P I _ C O M M _ W O R L D) ; i t e r e _ c h a l e u r(rp,NULL,rc)

}e l s e{

if(r a n k%2) { // n o e u d i m p a i r e

M P I _ S e n d r e c v(rc,2048 ,M P I _ F L O A T,rank-1 ,0 ,rp,2048 ,M P I _ F L O A T,rank-1 ,1 , M P I _ C O M M _ W O R L D) ;

M P I _ S e n d r e c v(rc,2048 ,M P I _ F L O A T,r a n k+1 ,2 ,rs,2048 ,M P I _ F L O A T,r a n k+1 ,3 , M P I _ C O M M _ W O R L D) ;

}

e l s e{ // n o e u d p a i r e

M P I _ S e n d r e c v(rc,2048 ,M P I _ F L O A T,r a n k+1 ,1 ,rs,2048 ,M P I _ F L O A T,r a n k+1 ,0 , M P I _ C O M M _ W O R L D) ;

M P I _ S e n d r e c v(rc,2048 ,M P I _ F L O A T,rank-1 ,3 ,rs,2048 ,M P I _ F L O A T,rank-1 ,2 , M P I _ C O M M _ W O R L D) ;

(47)

Exemple : SendRecv

(48)

Communication non-bloquante

Les op´erations SEND et RECV sont s´epar´ees en deux appels. Le premier permet de commencer la communication sans attendre que l’´ecriture ou la lecture soit termin´ee. Le second permet de savoir quand l’op´eration est termin´ee. Cela permet de superposer les communications et les calculs.

MPI IXSEND(buf,count,datatype,dest,tag,comm,request)

MPI IRECV(buf,count,datatype,source,tag,comm,request)

L’objet request contient des informations sur le mode de communication, sur l’enveloppe et le status de la communication

(49)

Communication non-bloquante

Pour compl´eter une communication, on utilise les commandes suivantes :

MPI WAIT(request,status)

MPI WAITANY(count,array of request,index,status)

MPI WAITALL(count,array of request,array status)

MPI WAITSOME(incount,array request,outcount, array index,array status)

MPI TEST(request,flag,status)

MPI TESTANY(count,array of request,index,flag,status)

MPI TESTALL(count,array of request,flag,array status)

MPI TESTSOME(incount,array request,outcount, array index,array status)

(50)

Exemple : communication non-bloquante

// C o m m u n i c a t i o n c i r c u l a i r e

# i n c l u d e < s t d i o . h >

# i n c l u d e " mpi . h "

int m a i n (int argc, c h a r* a r g v[]) {

int n u m t a s k s, rank, next, prev, buf[2] , t a g 1=1 , t a g 2=2;

M P I _ R e q u e s t r e q s[ 4 ] ; M P I _ S t a t u s s t a t s[ 4 ] ; M P I _ I n i t(&argc,&a r g v) ;

M P I _ C o m m _ s i z e(M P I _ C O M M _ W O R L D, &n u m t a s k s) ; M P I _ C o m m _ r a n k(M P I _ C O M M _ W O R L D, &r a n k) ; p r e v = rank-1; n e x t = r a n k+1;

if(r a n k == 0) p r e v = n u m t a s k s - 1;

if(r a n k == (n u m t a s k s - 1) ) n e x t = 0;

M P I _ I r e c v(&buf[0] , 1 , MPI_INT, prev, tag1, M P I _ C O M M _ W O R L D, &r e q s[ 0 ] ) ; M P I _ I r e c v(&buf[1] , 1 , MPI_INT, next, tag2, M P I _ C O M M _ W O R L D, &r e q s[ 1 ] ) ; M P I _ I s e n d(&rank, 1 , MPI_INT, prev, tag2, M P I _ C O M M _ W O R L D, &r e q s[ 2 ] ) ; M P I _ I s e n d(&rank, 1 , MPI_INT, next, tag1, M P I _ C O M M _ W O R L D, &r e q s[ 3 ] ) ; M P I _ W a i t a l l(4 , reqs, s t a t s) ;

p r i n t f(" T a s k % d c o m m u n i c a t e d w i t h t a s k s % d & % d \ n ",rank,prev,n e x t) ;

(51)

Table des mati` eres

1 Programmation parall`ele

2 OpenMP Directives Clauses

Concurrences et synchronisation

3 MPI

Messages

Communications collectives

4 Conclusion

(52)

communications collectives

(53)

Communications collectives

MPI BCAST(buf,count,datatype,root,comm)

MPI GATHER(sendbuf,sendcount,sendtype, recvbuf,recvcount,recvtype,root,comm)

MPI SCATTER(sendbuf,sendcount,sendtype, recvbuf,recvcount,recvtype,root,comm)

MPI ALLGATHER(sendbuf,sendcount,sendtype, recvbuf,recvcount,recvtype,comm)

MPI ALLTOALL(sendbuf,sendcount,sendtype, recvbuf,recvcount,recvtype,comm)

(54)

R´ eduction

Possibilit´e de faire une r´eduction avec des op´erations pr´ed´efinies ou d´efinies par l’usager(MPI OP CREATE).

MPI REDUCE(sendbuf,recvbuf,count,datatype,op,root,comm)

MPI ALLREDUCE(sendbuf,recvbuf,count,datatype,op,comm) Les op´erations pr´ed´efinies sont :

MAX,MIN,SUM,PROD,LAND,BAND,LOR,BOR,LXOR,BXOR,MAXLOC et MINLOC

(55)

Exemple : calcul de pi

// g e n e r e c o o r d o n n e e x et y

v o i d r a n d o m _ c o o r d(d o u b l e* x,d o u b l e* y) int m a i n(int argc, c h a r *a r g v[]) {

int rank, size, i e r r; M P I _ S t a t u s s t a t u s;

int r o o t = 0;

d o u b l e N _ t r y = 1 0 0 0 0 0 d o u b l e h i t _ l o c a l =0;

d o u b l e h i t _ t o t a l = 0;

i e r r = M P I _ I n i t(&argc,&a r g v) ;

i e r r = M P I _ C o m m _ s i z e(M P I _ C O M M _ W O R L D,&s i z e) ; i e r r = M P I _ C o m m _ r a n k(M P I _ C O M M _ W O R L D,&r a n k) ; for(int i=0; i< N _ t r y; i++) {

d o u b l e x,y,n o r m; r a n d o m _ c o o r d(&x,&y) ; n o r m = x*x +y*y

if (n o r m < 1) {h i t _ l o c a l++}

}

i e r r = M P I _ R e d u c e(&h i t _ l o c a l,&h i t _ t o t a l,1 ,M P I _ D O U B L E, MPI_SUM,root,M P I _ C O M M _ W O R L D)

if(r a n k == r o o t) {

d o u b l e pi = 4*h i t _ t o t a l/N _ t r y;

}

i e r r = M P I _ F i n a l i z e() ;

Figure Calcul de pi

(56)

Autre type d’op´ eration globale

MPI REDUCE SCATTER(sendbuf,recvbuf,recvcount, datatype,op,comm) : redistribue le r´esultat de la r´eduction

MPI SCAN(sendbuf,recvbuf,count,datatype,op,comm) : r´eduction avec pr´efixe

MPI EXSCAN(sendbuf,recvbuf,count,datatype,op,comm)

MPI BARRIER(comm)

(57)

Les points importants

Attention aux situations d’interblocage.

Les communications non bloquantes permettent d’effectuer des calculs en mˆeme temps.

S’assurer que les communications sont parall`eles (si possible)

(58)

Table des mati` eres

1 Programmation parall`ele

2 OpenMP Directives Clauses

Concurrences et synchronisation

3 MPI

Messages

Communications collectives

(59)

A retenir ! `

La loi d’Amdhal.

La diff´erence entre un thread et un processus.

OpenMP cr´ee des groupes de threads afin d’ins´erer des blocs parall`eles dans un code.

MPI est un standard de communication inter-processus.

Faites attention aux probl`emes de concurrence et aux situations d’interblocages.

Une panoplie de tutoriels sur openMPI et MPI sont disponibles sur internet.

On retrouve les documentations officielles aux adresses suivantes : - www.openmp.org

- mpi-forum.org

(60)

questions ?

G. Emond (PolyMtl) GPS-OpenMP/MPI 2016 60 / 60

Références

Documents relatifs

On monte le moteur, soit dans un trou carr ´e avec deux petits vis, soit entre deux plaques en bois. Apr `es on colle la pi `ece d ´etach ´ee

Soit H un point du segment [AD]. distincts de

Soit H un point du segment [BC]. distincts de

[r]

Plutˆ ot que n´ ecessiter de recompiler le module pour chaque nouvelle op´ eration, nous d´ esirons exposer une interface ` a l’utilisateur de fa¸ con ` a ce que deux ´

Problème initial est décomposé en tâches de calcul Tâches s’exécutent en parallèle. Tâches travaillent sur des données

Un exemple de thread d’interface : L’explorateur de Windows, en fait si vous aller dans le Gestionnaires de Tˆ ache (NT ou 2000) ou que vous appuyez sur Ctrl+Alt+Del (sous Win9x)

● La boucle while du thread qui affiche consomme tout le temps CPU car le thread ne passe jamais la main aux autres threads... PERACHE Marc Programmation Parallèle et