Algorithmique parallèle
description
Transcript of Algorithmique parallèle
Algorithmique parallèle
1. Construction et analyse d’algorithmes B. Le Cun
2. Synthèse par transformation S. Rajopadhye
3. Synthèse par interprétation J.-L. Roch
Un exemple
void explore( nœud n, …) { if … { for (s =n.first(); s <n.last(); n++)
{ dopar explore( s, …) ; }}
h
T1 : tps séquentiel
T = O(h)
S1 = O(h)
Texec(p) ~ T1 /p (1+)
Sexec(p) = S1 O(1)
tâche
De l’algorithme à la machine : Synthèse par interprétation
Programme
parallèle
T1, T :Class f {operating()( shared_r_w<int> x ) {x = sin(x->val ) * BB(taq ( x ) ) ;}
void main(int argc, char* argv) {Fork<f> ( shared<int> (3) ) ;}
Interprétation=
Analyse de flot +ordonnancement
a b
H(a) O(b,7)
F(2,a) G(a,b) H(b)
Sisal, Cilk, Ath1,…
Exécution
efficace
Langages data flow
Fonctionnel [70, …]
Calcul par nécessité
Haskell [Arvind 70, …MIT ]
Sisal [ 90, Gaudiot USC]
…
mémoire
Parallélisme [80, …]
– Ordonnancement efficace
- fonctionnelMultilisp [Halstead 86, MIT]
Prolog [Chassin 88] Mars-ML [Lecussan 88]
Sisal [Sohn, 98 NJIT] Nesl [Blelloch 96 Cornell]
- impératif : Macro data flowJade [Rinard 95, Stanford] Earth [Gao 98 UD]
Cilk [Leiserson 98, MIT]Athapascan-1 [Roch 98]
temps + mémoire
détection (dynamique) des dépendances
Plan
1. Ordonnancement d’un graphe: calcul et contrôle
2. Interprétation data flow : techniques de base
3. Optimisation dynamique du grain
4. Optimisation dynamique des accès mémoire
• Contrôle de l’explosion mémoire
– Entrée : un graphe de précédence, pas un programme
– Sortie : un placement des tâches et des données
• Analyse de l’ordonnancement : comparaison à l’optimal
• Coût de calcul et de gestion généralement ignorés :– Coût de calcul polynomial en le nombre de tâches -> T1
O(1)
Ordonnancement : cadre théorique
a b
H(a) O(b,7)
F(2,a) G(a,b) H(b)
Exemples d’ordonnancements• Ordonnancement glouton : minimiser l’inactivité [Graham66]
T1 = durée d’une exécution séquentielle
T = durée d’un chemin critique )(1
NpNtTP
TTp + surcoût
))log(( tt NpNO Tp
Tp
T1
• Prise en compte des latences liées au réseau :ex : analyse de coûts de communication : ETF / ERT [Hwang89]
C1 = volume total de communicationsC = volume des communications sur un chemin critique = délai de communication d’une donnée
C + surcoût
Surcoût pour réaliser l’ordonnancement • Contrôle :
– création/placement/entrelacement des tâches
– gestion de la mémoire, mouvements de données
– préemptivité, réactivité
• Exemple : algorithme récursif d’exploration– Ordonnancement glouton : théorique = OK
– Mais réalisation ???• Nombre de tâches ~ T1 …
• Mémoire ~ 2h … en séquentiel ~ h
h
Contrôle ordonnancement sur grappe
• Surcoût– local sur SMP :
• détection locale des données disponibles : fins d’accès locaux• gestion locale des tâches prêtes sur threads dédiés
– global entre nœuds SMP : • Calcul des synchronisations : bilan des fins d’accès locaux• si inactivité : envoi d’une requête à un autre nœud• Surcoût de réactivité
Plan
1. Ordonnancement d’un graphe: calcul et contrôle
2. Interprétation data flow : techniques de basedistribué, SMP, séquentiel
3. Optimisation dynamique du grain
4. Optimisation dynamique des accès mémoire
Interprétation data-flow (1)• Détecter dynamiquement les synchronisations :
dépendance écriture -> lecture
• Variables vues en assignation unique [sisal…]:
– Une tâche lit des valeurs en mémoire;
– L’effet d’une tâche est d’écrire des valeurs en mémoire;
• En cours d’exécution d’une tâche, une variable a deux versions : – version courante : ce qui est lu : valeur précédente avant l’instruction courante
– version future : ce qui sera écrit : valeur résultant de l’exécution de l’instruction sera vue par les successeurs
Interprétation data-flow (2)
• Lors de la création de tâches : dopar f(x,…) ;– création d’une nouvelle version pour les variables modifiées par la tâche créée
courante côté appelant == future côté appelé
courante
future
Avant
dopar f(x)
X future
courante
x côté exécution f(x)
X local après dopar f(x)
courante
• En fin d’accès à une variable : release• La version «future / courante » devient prête :
• ramassage de l ’ancienne version courante • les successeurs de f(x) deviennent prêts
Interprétation data-flow (3)
• Calculer si une version est prête :– fin écriture => lecture possible
– fin lecture : écriture en place/ramassage mémoire possible
• Implémentation de la gestion des versions :– dépend de la sémantique des accès mémoire
– Distribuée, SMP, Séquentielle
Implémentation distribuée• Une même version est distribuée sur plusieurs sites:
– nommage : site de création + indice sur le site : x = <site, indice>
• Calculer si une version est prête :– Terminaison distribuée
• Exemple:
bilan + cptr local id site de ref + cptr local
Version sur
site de référenceVersion sur
autre site
Version[x] Version[x]
Implémentation SMP
• Compteur local sur chaque version :– nombre d ’accès en cours : prêt <=> cptr==0
Courante cpt
Future cpt
T& val
Implémentation séquentielle (DF)
• ordonnancement d’une tâche = appel de fonction
dopar f( x );
• version courante == version future : stockage en place
x
courante
future
x implantation
f(x)implantation
Interprétation data flow
• Efficace à gros grain en distribué et smp mais …
• Surcoût de contrôle dû à l’interprétation
• Comment gérer de nombreuses synchronisations ?
• Analogie : interprétation vs compilation– Comment compiler (à la volée) l’ordonnancement ? …JIT
Plan
1. Ordonnancement d’un graphe: calcul et contrôle
2. Interprétation data flow : techniques de base
3. Optimisation dynamique du grain
dégénération séquentielle
4. Optimisation dynamique des accès mémoire
Tirer parti d’un ordt séquentiel efficace• Programme très parallèle :
– beaucoup de tâches créées et exécutées localement [Blumhoffe]
• void prog() {<i1>
spawn f1 (args ) ;
… //autres spawn
Sync
<fin>
}
<i1>
f1(args) …
<fin>
fk(args)
sync
• Mettre le surcoût d’ordt lors du vol :éviter les créations de tâches, remplacées par des appels de fonction
Quand est-ce possible ?
• Lors d’une création, il faut pouvoir dégénérer en appel de fonction profondeur d’abord :– Sémantique séquentielle possible
– Être sûr que la tâche est prête à être exécutée– Exemples : multilisp [86], Prolog,…, Cilk [98], …
• Deux versions d’une fonction :– Séquentielle - Création/exécution d’une tâche
Dégénération séquentielle « active »
• Principe : test si processeur inactif avant de dégénérer
<i1>
f1(args) …fk(args)
Si pas de requête de tâches {
dégénération séquentielle
f(args1) ;… }
Processeur actif
Ordt compilé
• Création de deux tâches : exportation + synchronisation
Processeur inactif
Ordt interprété<fin>
syncf1(args)
Sinon {création tâche pour f1(args)}
Dégénération séquentielle « passive »
• Principe : si requête de vol, vol de la continuation
<i1>
f1(args) …
<fin>
fk(args)
sync
// dégénération séquentielle<i1> ;
Préparation continuation exportable;
f(args1) ; // version rapide
Processeur actif
Ordt compiléProcesseur inactif
Ordt interprété
<i2…>
…
<fin>
fk(args)
sync
Si (continuation volée){
signaler sync; return;
}
Sinon suite idem…
SMP : durée = f( seuil )temps séquentiel pour 1 processeur pour 2 processeurs
Dégénération séquentielle - Conclusion
• Théorique sur SMP : si programme parallèle strict
• Pratique : contrôle automatique de granularité [Galilée98]
)(1
NpNtTP
TTp + O( p.T)
Sans dégénération séq [Ath-1]
Avec dégénération séq [Cilk]
Environ 220 tâches de grain 1
Ath-1
Cilk
Plan
1. Ordonnancement d’un graphe: calcul et contrôle
2. Interprétation data flow : techniques de base
3. Optimisation dynamique du grain
4. Optimisation dynamique des accès mémoiredégénération distribuée
Optimiser les accès mémoire
• Si beaucoup de synchronisations :– efficacité si localité
• Analyse data flow => Les accès distants sont prévisibles – Pré-calcul de sites pour tâches et données (écriture locale) [ETF]
• Accès mémoire « compilé » == pointeur local ou communication « uni-directionnelle »
Dégénération distribuée
• Surcoût mis lors de non respect de la localité
Exemple
• Pré-affectation tâches/versions aux processeurs
a b
H(a)I(a,b)
F(a) G(b)
Accèsmémoire
comm
send
recv
Processeur 1 Processeur 2
a
Algorithme d’interprétation• Hypothèse : graphe calculé dynamiquement (partiellement)
• Version = ptr+ressource de communication (ex: tag mpi)
• En fin d’écriture, diffusion à tous les sites lecteurs– Regroupement des communications / contrôle scrutation
• Côté lecteur : – pré-allocations pour les réceptions
– Ordonnancement dynamique des tâches prêtes
• NB: le pré-placement peut être modifié dynamiquement
Dégénération distribuée - Conclusion• Théorique : sur modèle délai : latence =
Tp
Tp
T1
C + O( p.n2 + .n)
0
100
200
300
400
500
600
700
400 800 1200 1600 2000 2400
Scalapack A1 glouton A1 bi-dim A1-JITcom
ScaLapack/MPIbloc-bidim 16 proc
Dégénération distribuéebloc-bidim
gloutonBloc bidimsans dégénération
DTPORF 5000 tâches
16 procs (IBM-SP1)
MFlops = f( taille )
Dégénération distribuéeETF
[Doreille99]
Plan
1. Ordonnancement d’un graphe: calcul et contrôle
2. Interprétation data flow : techniques de base
3. Optimisation dynamique du grain
4. Optimisation dynamique des accès mémoire
Conclusion (1)• Langages « macro data flow »:
– JIT Analyse (implicite) des dépendances– Calcul d’ordonnancement
• Contrôle de l’ordonnancement :– Techniques pour optimiser le surcoût de contrôle
Dégénération séquentielle Dégénération distribuée
– Intégration dans d’autres langages• Dégénération séquentielle dans Open-MP ?
• Spécialisation automatique :– Les techniques peuvent être couplées entre elles– Vers un ordt générique avec auto-spécialisation
0
1000
2000
3000
4000
5000
6000
7000
8000
9000
taille
Mfl
ops
Athapascan Scalapack
dtrporf : grappe de 64 processeurs• 16 quadri-processeurs [Univ. Delaware]
– Grappe SUNs[Solaris] + Myrinet – bande passante 30Mo/s , latence 60µs– 1560 Mflops par nœuds = 25000 Mflops.
Exploitation mémoire partagée Ordonnancement « plus dynamique »
–Dégénération distribuée entre nœuds
–Ordt glouton optimisé SMP sur chaque noeud
[Athapascan-1 – 60000 tâches]
[Bloc bidim/MPI]
Conclusion (2)
• Construction d’un algorithme parallèle efficace :– À la main : algorithmique parallèle
– Automatiquement par transformation d’un programme séquentiel
• Exécution d’un programme parallèle– Automatiquement par interprétation d’un programme parallèle
• Intérêt d’un ordonnancement séquentiel efficace + Prédiction dépendances
– À la main : écriture d’un programme spécifique
• La synthèse automatique permet, sous certaines restrictions, la portabilité avec performances
Fichiercompressé
Fichieren entrée
Compressionà la volée
Programme
Partition dynamique en blocs
Comment paralléliser gzip ?
Parallélisation
Blocs compressés
Compressionparallèle
Partition dynamique en blocs
Si processeur inactif : nouveau bloc