Sources du parallelisme

Transcription

Sources du parallelisme
Master Info
Parallélisme et Répartition
Françoise Baude
Université de Nice Sophia-Antipolis
UFR Sciences – Département Informatique
[email protected]
web du cours : deptinfo.unice.fr/~baude
Septembre 2009
Chapitre 1 : Introduction générale
Chapitre 2 : Paradigmes de programmation parallèle
1
Plan
1.
2.
3.
4.
5.
Les différentes Sources de parallélisme
Le parallélisme de données
Le parallélisme de contrôle
Modèles de langages parallèles
Petite introduction à OpenMP
2
1
1. Les différentes sources de parallélisme
Savoir identifier les formes de //sme
Exploitation du parallélisme dans une
application
peut provenir de plusieurs sources
Plein de Données a traiter de la même manière
Ex: Exploité par les ordinateurs // « SIMD »
Appelé Parallélisme de Données
Plein/plusieurs de taches indépendantes sur
données différentes
Ex: Exploité par les ordinateurs // « MIMD »
Appelé Parallélisme de Contrôle
Flot de données selon une séquence de traitement
Ex: Exploité par les processeurs (pipeline)
Appelé Parallélisme de Flux
3
Exemple [Gengler/Ubeda/Desprez] (1)
Pour i=0 à (n-1) faire
vv[i]=a + b.v[i]2 + c.v[i]3 + d.v[i]4 + e.v[i]5 + f.v[i]6 + g.v[i]7
finPour
formule avec v[i] n’interfère pas avec celle avec v[j], i ≠ j
Extraction de parallélisme issu des n données :
Pour i=0 à (n-1) faire_en_parallele (hyp. sur n proc ! )
vv[i]=a + b.v[i]2 + c.v[i]3 + d.v[i]4 + e.v[i]5 + f.v[i]6 + g.v[i]7
finPour
Accélération (théorique) du calcul séquentiel d’un facteur n
4
2
Graphe sous-jacent, taches et liens (1)
local
ev=v[0]
ev=a+b.ev2+
c.ev3+d.ev4+
e.ev5+f.ev6+
g.ev7
vv[0]=ev
local
ev=v[1]
ev=a+b.ev2+
c.ev3+d.ev4+
e.ev5+f.ev6+
g.ev7
vv[1]=ev
local
ev=v[2]
ev=a+b.ev2+
c.ev3+d.ev4+
e.ev5+f.ev6+
g.ev7
vv[2]=ev
…….
local
ev=v[n-1]
ev=a+b.ev2+
c.ev3+d.ev4+
e.ev5+f.ev6+
g.ev7
vv[n-1]=ev
…….
Largeur du graphe « n »: degré
d’accélération (théorique) du
calcul séquentiel
Point de
Synchronisation
(implicite)
« fin pour »
Profondeur du graphe O(1):
complexité en temps parallèle
Vecteur vv est dispo
5
Remarques générales
Granularité tache ?
Doit être suffisante pour masquer le surcout de création des
taches (et aussi des threads)
Graphe permet de voir le //sme maxi
Mais en réalité, souvent moins de proc. !
Ordonnanceur efficace de taches sur les threads
sinon qui peut délimiter les taches en fonction des proc.
dispo?
Compilateur (parallélisation auto.)
Ou bien c’est le programmeur Hyp. sur p processeurs, chaque proc. d’identifiant idproc Є [0..p-1]
exécute :
ind =idproc * (n / p)
Pour i=ind à ind + n/p – 1 faire
vv[i]=…
finPour
6
3
Exemple [Gengler/Ubeda/Desprez] (2)
Extraction de parallélisme en délimitant des taches
de même granularité si possible
a + b.v[i]2 + c.v[i]3 + d.v[i]4 + e.v[i]5 + f.v[i]6 + g.v[i]7
=(a+ b.v[i]2+c.v[i]3)+ v[i]4 *(d+ e.v[i] + f.v[i]2 + g.v[i]3)
+
y
x
pour chaque itération i :
*
z
3 taches Parallèles: input=v[i], output=(calcul de la tache)
Mais qui doivent s’attendre pour exécuter le + et le *
Pour i=0 à (n-1) faire
taches_paralleles :
Accélération (théorique) du calcul
séquentiel d’un facteur 3
x = a + b.v[i]2 + c.v[i]3
y = d+ e.v[i] + f.v[i]2 + g.v[i]3
z = v[i]4
fin taches_paralleles
vv[i]= x + z * y
finPour
7
Graphe sous-jacent, taches et liens (2)
i -1
local ev
ev=v[i]
x=a+b.ev2+
c.ev3
local
ev=v[i]
z=ev4
local
ev=v[i]
y=d+e.ev+
f.ev2+g.ev3
z
y
x
vv[i]=x+z*y
Element vv[i] dispo
« Fausse » dépendance:
Uniquement là parce que
FinPour
local ev
ev=v[i+1]
x=a+b.ev2+
c.ev3
Largeur du graphe « 3 »:
degré de //sme, facteur
d’accélération du calcul séquentiel
Profondeur du graphe
O(1) * n = O(n)
complexité en temps parallèle
local
ev=v[i+1]
z=ev4
z
local
ev=v[i+1]
y=d+e.ev+
f.ev2+g.ev3
y
x
vv[i+1]=x+z*y
…….
Element vv[i+1] dispo
i+2
Vecteur vv est dispo
8
4
Exemple [Gengler/Ubeda/Desprez] (3)
Extraction de parallélisme en exprimant un flux
Nécessité de reformuler !
a + b.v[i]2 + c.v[i]3 + d.v[i]4 + e.v[i]5 + f.v[i]6 + g.v[i]7
= a + v[i]*(0+v[i]*(b+v[i]*(c+v[i]*…(f+v[i]*(g+v[i]*0))…)))
pas de facteur
en v[i]
v[i]
v[i]
a
X
v[i]
v[i]
0
b
c
c+v[i]*(Y)
X
v[i]
v[i]
…
f
Y
f+v[i]*(g)
v[i]
v[i]
g
0
g+v[i]*0
X
Accélération (théorique) du calcul
séquentiel d’un facteur = nombre
étages du pipeline, ici 8 (si vecteur v
suffisamment long, voir TD1)
coeff
coeff + X*Y
Y
9
2. Le parallélisme de données
Parallélisme de données: map/reduce (1)
Généralement bien adapté à une structure de
données (« collection » de données ou de collections)
De grande taille => c’est la source de //sme !
Régulière => le degré de //sme dépend juste de la taille de
la donnée, et non de sa valeur
Ex. classiques: vecteur, matrice, tableau
Opérations habituelles : map et reduce
1. Appliquer un traitement similaire à chaque élément, de
manière indépendante, afin de transformer la donnée//
Pattern « Map » (terminologie prog. Fonctionnelle), ou alpha
Traitement: fonction f(x_i) -> y_i, pour i quelconque
Appliquer f sur chaque élément x_i afin de
calculer/transformer la donnée globale X en Y : f(X) -> Y
Pas de dépendance entre les traitements élémentaires, donc,
« map » est 1 opération globale naturellement parallélisable.
x0
x1
x2
x3
x4
x5
x6
x7
y0
y1
y2
y3
y4
y5
y6
y7
10
5
Parallélisme de données: map/reduce (2)
2. Calculer une valeur unique en combinant
(réduisant) l’ensemble des x_i -> nouvelle donnée
Pattern « Reduce » (terminologie prog. Fonctionnelle),
ou beta
Traitement: fonction binaire (pas forcément
commutative), associative g(x, y) -> z
Appliquer g de sorte que chaque élément x_i de la
donnée globale soit pris en compte exactement une fois
Calcul parallèle engendre des taches dépendantes 2 à 2
x0
log2 n
étapes
Degré
//sm
maxi: n/2
x1
x2
z01
x3
x4
z23
x5
x6
z45
x7
z67
z4567
z0123
z01234567
11
Map et reduce
Utilisés ensemble:
Un potentiel énorme !
Prouvable que tout calcul
qui forcement, consiste à travailler sur des données
peut s’exprimer en un enchainement séquentiel
(composition de fonctions) de maps et reduces sur ces
données
Le tout est de trouver les bons operateurs f, g !
Ex. (partiel) multiplication de deux matrices
By1
A1x
+
* * * *
*
=
……….
En // pour tous les x Є [1..n] et y [1..n]: //
1)Exécuter un produit vecteur*vecteur
(chaque produit est un map sur vect)
2) Puis réduire par + en un scalaire
* * * *
//
…..
+
12
6
Multiplication matrice map/reduce
Une version pas purement « fonctionnelle » !
En // pour tous les x Є [1..n] et y [1..n]:
1)Exécuter un produit vecteur*vecteur
(chaque produit est un map sur vect)
2) Puis réduire par + en un scalaire
Pour i=0 à (n-1) faire_en_parallele
Pour j=0 à (n-1) faire_en_parallele
mat[i,j] = reduce(+, map( *, A_[i,…], B[…,j]) )
finPour
finPour
Une version purement « fonctionnelle »
•Une matrice = collection (linéaire, représentation à plat) de n vecteurs
•2 matrices M1, M2 combinées en un produit scalaire de leurs vecteurs respectifs en ligne
et en colonne (une combinaison complexe de map et reduce): on obtient une collection
[ (Ligne1_M1, Colonne1_M2), (Ligne1_M1, Colonne2_M2), … ,
(Lignen_M1,Colonnen_M2)] => problème difficile: générer, stocker cette var. intermédiaire
En // pour toutes les paires de cette collection => c’est un map dont la fonction est :
1) un produit vecteur*vecteur, ce produit est lui-même exprimé comme un map dont la
fonction est un * entre chaque élément scalaire de chaque vecteur -> un nouveau vect.
suivie 2) d’une réduction de ce nouveau vect. par +, scalaire qui remplace la paire 13
3. Le parallélisme de contrôle
Décomposition selon flot de contrôle
Découpage fondé sur le ‘flot de contrôle’ du
programme afin de délimiter des taches:
branchements (2 taches),
boucles (1 tache par [1..x] tours de boucle),
fonctions (1 tache par appel) (ex: lges // fonctionnels !)
Manuel : découpage arbitraire d’une section de code
séquentielle (profitant éventuellement du flot des données)
Bien adapté si de nombreuses taches engendrées ! :
De granularité (quantité de travail) similaire
Pas d’attente inutile due à une tache lente
Suffisamment grosses pour masquer surcout engendré
Ayant le moins de dépendances de données entre elles
14
7
Diviser « pour régner » (ici : « pour
paralléliser ») / Divide and Conquer
Fondé sur décomposition (souvent) récursive du
problème à résoudre en problèmes (si possible)
similaires mais plus petits
Principe:
Découper le problème (si assez gros) en sous-problèmes
résoudre tous les sous problèmes en //
Etape bloquante pour combiner leurs résultats
Pattern algorithmique bien adapté pour profiter de la
source de parallélisme « contrôle »
beaucoup de taches, et dynamique
15
Programmation de la répartition des
taches : devient le fil de contrôle!
On ne connaît pas à l’avance
le nombre de CPUs disponibles
le nombre de taches qui va être généré par l’exécution
=> la gestion, le contrôle de tout ceci est très complexe
Le programme parallèle est organisé en fonction d’une
stratégie afin de mieux piloter comment engendrer et
répartir des taches
Pattern Maitre / esclaves
Pattern Sac de taches (« vol » de taches)
… généralisation à des squelettes (schémas tout prêts et
personnalisables) : ferme, pipeline, M/E, fork/join
16
8
4. Modèles de langages parallèles
Modèle de programmation, modèle
d’exécution
17
Ambivalence des modèles :
exécution ou programmation ?
Les langages de programmation parallèle sont
parfois aussi des langages (bas niveau) pour
l’exécution :=(
18
9
Types de langages // (1)
Langages de programmation // implicite
Modèle séquentiel plus parallélisation automatique:
Analyse des dépendances de données par un compilateur
‘parallélisant’
Difficile
Revient très à la mode avec le multi-coeur
Le runtime du langage gère entièrement les
activités parallèles
Le programmeur ne spécifie rien quant au
placement et ordonnancement des taches, et
manière de répartir les données sur les taches (si
modèle d’accès mémoire sous-jacent est réparti)
19
Types de langages // (2)
Langages de programmation // explicite
Le programmeur est responsable de la parallélisation:
Décomposition en taches
Placement des taches
Gestion Communication et synchronisation
Plusieurs classes de langages:
Directives de contrôle sur les boucles, délimitation de régions
de code parallèle (ex: OpenMP)
Distribution de (grandes) structures de données: ex: High
Performance Fortran => placement données induit taches //
Modèles distribués (répartis): Parallel Virtual Machine ,
Message Passing Interface, ProActive
20
10
5. Petite introduction à OpenMP
Va nous permettre d’exploiter toutes les
formes de parallélisme de contrôle
En supposant un modèle d’exécution à espace
d’adressage unique
21
22
11
OpenMP: Shared Memory
Application Programming Interface
► Multiplatform shared memory multi-threads
programming
► Compiler directives, library routines, and
environnement variables
► For C++ and Fortran
► Cours en ligne sur www.openmp.org
ActiveEon Training March 08
23
OpenMP: General Concepts
► An OpenMP program is
executed by a unique
process
► This process activates
threads when entering a
parallel region
► Each thread executes a
task composed by
several instructions
► Two kinds of variables:
Local
variables
Shared
variables
Thread
Program
Parallel
region
Process
Set of
instructions
Private
Shared
ActiveEon Training March 08
24
12
OpenMP
► The programmer has
to introduce OpenMP
directives within his
code
fork
parallel
region
► When program is
executed, a parallel
region will be created
on the “fork and join”
model
join
ActiveEon Training March 08
25
OpenMP: General Concepts
0 1
ActiveEon Training March 08
3
Nb. Tasks
Time
► An OpenMP program
is an alternation of
sequential and
parallel regions
► A sequence region is
always executed by
the master task
► A parallel region can
be executed by
several tasks at the
same time
2
26
13
OpenMP: General Concepts
► A task is affected to
a processor by the
Operating System
Task Manager
Processors
ActiveEon Training March 08
27
28
14
OpenMP: Work-sharing Concepts
X=a+b
Do i= …
……..
……….
End do
Looplevel
parallelism
Call sub(..)
call sub(..)
do i= ..
end do
Parallel
sections
Parallel procedure
(orphaning)
ActiveEon Training March 08
29
OpenMP: Synchronization Concepts
► Concurrency
problems
► The need of task
synchronization
ActiveEon Training March 08
a=2
b=3
S=0
………
……….
S=?
S=6
S=12
Do i= …
S=S+a*b
End do
30
15
31
32
16
33
OpenMP Basics: Parallel region
► inside a parallel region:
by default, variables are
shared
all concurrent tasks
execute the same code
Program parallel
use OMP_LIB
implicit none
real ::a
logical ::p
a=9999. ; p= false.
!$OMP PARALLEL
!$ p = OMP_IN_PARALLEL()
print *, “A value is :”,a &
“; p value is:
”,p
!$OMP END PARALLEL
► there is a default
synchronization barrier at
end program parallel
the end of a parallel region
> export OMP_NUM_THREADS=3; a. out;
> A value is 9999. ; p value is: T
> A value is 9999. ; p value is: T
> A value is 9999. ; p value is: T
ActiveEon Training March 08
34
17
OpenMP Basics: Parallel region
Program parallel
By using the DEFAULT
use OMP_LIB
implicit none
clause one can change the
real ::a
a=9999.
default status of a variable
!$OMP PARALLEL DEFAULT(PRIVATE)
a=a+10.
within a parallel region
print *, “A value is : ”,a
!$OMP END PARALLEL
If a variable has a private end program parallel
status (PRIVATE) an
instance of it (with an
undefined value) will exist
in the stack of each task.
a=9999
> export OMP_NUM_THREADS=3; a. out;
a=10
a=10
> A value is : 10
a=10
> A value is : 10
> A value is : 10
ActiveEon Training March 08
35
OpenMP: Synchronizations
Automatic update
► The ATOMIC directive
guarantees that a shared
variable is read and
modified by a single task at
a given moment
x
time=1
x
x=f(x,exp)
time=0
time=2
x
ActiveEon
ActiveEon
Training
Training
MarchMarch 08
08
36
18
OpenMP : Synchronizations
Critical Region
program parallel
► defined with the CRITICAL
implicit none
integer :: s, p
directive
s=0 ; p=1
!$OMP PARALLEL
!$OMP CRITICAL
► generalization of ATOMIC
s = s + 1
p = p * 2
directive
!$OMP END CRITICAL
!$OMP END PARALLEL
► tasks in the critical region
print *, "s=", s, " ; p=", p
end program parallel
are executed in an undeterministic order but one
by one.
> xlf_r ... -qsmp=omp prog.f90
> export OMP_NUM_THREADS =4 ; a.out
> s= 4 ; p= 16
ActiveEon
ActiveEon
Training
Training
MarchMarch 08
08
37
38
19