Algorithmique Parallèle
CSC5001 – Systèmes Hautes Performances
Objectifs
●
Savoir répondre aux questions suivantes:
● Quel gain potentiel à paralléliser une application ?
● Quel est le coût d’une communication réseau ?
● Comment découper une application pour la rendre parallèle ?
● Comment répartir le travail de manière équitable ?
Architectures parallèles
● Au sein d’un processeur
● Cœurs de calcul, hyper-threading, superscalaire, vectorisation
● Au sein d’une machine
● SMP (Symmetric Multi Processor), NUMA (Non-Uniform Memory Architecture)
● Entre machines
● Grappes de calcul
Modèles de programmation
Modèles à mémoire partagée
●
Chaque tâche a accès à toutes les données
●
Répartition des traitements
●
Limiter les synchronisations entre tâches
→ OpenMP, Pthread, Intel TBB
Modèles à mémoire distribuée
●
Chaque tâche a accès à ses propres données
●
Répartition des données et communications entre processeurs
●
Une tâche effectue le traitement lié aux donnée locales
– Règle « owner computes »
●
Limiter les communications entre tâches
→ MPI
Modèles hybrides
●
Modèle distribué pour répartir sur plusieurs nœuds
●
Modèle à mémoire partagée au sein d’un nœud
●
Permet de tirer partie de la topologie de la grappe
– Un processus MPI par nœud NUMA + threads OpenMP
– Un processus MPI par machine + CUDA
Taxonomie de Flynn
●
Classification des architectures
Single instruction Multiple
instruction Single
program Multiple programs Single data SISD
(proc séquentiel) MISD (avionique) Multiple data SIMD
(GPU, vector CPU) MIMD
(multicore, cluster) SPMD
(MPI) MPMD
(Cell/BE, CPU+GPU)
Quel gain potentiel à paralléliser une
application ?
Théorie du parallélisme
●
Parallélisation
– Utiliser plusieurs processeurs pour traiter un problème plus rapidement
– Généralement, seule une partie du problème peut se paralléliser
Loi d’Amdahl
● Loi d’Amdahl
– Accélération maximale théoriquement atteignable
– s = fraction du programme parallélisée
– 1-s = fraction du programme séquentielle
– r = 1 / (1-s) + (s/p)
1 2 4 8 16 32 64 128
256 512
1024 2048
4096 8192
16384 32768
65536 0
2 4 6 8 10 12 14 16 18 20
50%
75%
90%
95%
Nombre de processeurs
Accélération
Mesures de performances
●
Métriques de performance parallèle
– Evolution du temps d’exécution en fonction du nombre de processeurs p
– Accélération (en anglais, speedup): Sp = Ts/Tp
● Ts: temps d’exécution du meilleur algorithme séquentiel
● Tp: temps d’exécution de l’algorithme parallèle sur p processeurs
Courbes de speedup
●
Plusieurs classes de speedup
– Idéal : Tp = Ts/p
– Linéaire: Sp = α.Si (α<1)
– Asymptotique: Sp < β
– Superlinéaire: Sp > Si
● Dû à l’architecture (effets de cache)
● Dû à l’algorithme (algo de recherche)
0 5 10 15 20 25 30
0 5 10 15 20 25 30
Idéal Linéaire asymptotique superlinéaire
Nombre de processeurs
Accélération
Efficacité
●
Efficacité: E= S/p
– Mesure le taux d’occupation « utile » des processeurs
0 20 40 60 80 100 120 140
0 0,2 0,4 0,6 0,8 1 1,2
Idéal Linéaire asymptotique
Nombre de processeurs
Efficacité
0 5 10 15 20 25 30
0 5 10 15 20 25 30
Idéal Linéaire asymptotique
Nombre de processeurs
Accélération
Quel est le coût d’une communication
réseau ?
Topologies réseau
●
Comment connecter N machines à l’aide de switch 4-ports ?
– Arbre de switches
Topologies réseau
●
Comment connecter N machines à l’aide de switch 4-ports ?
– Arbre de switches
Fat tree
●
Comment connecter N machines à l’aide de switch 4-ports ?
– Fat Tree
Autres topologies
●
Beaucoup d’autres topologies.
●
Buts:
– Minimiser le nombre de sauts (~latence)
– Maximiser la bande passante
Tore 2D Tore 3D
00 0
0 0 11 0
22 33 44 55 66 77
00 11 22 33 44 55 66 77 0
1 0 1 0 2 0 2 0 3 0 3
1 0 1 0 1 1 1 1 1 2 1 2 1 3 1 3
2 0 2 0 2 1 2 1 2 2 2 2 2 3 2 3
0 1 0
Modèle de communication
●
Hypothèses
– Coût de communication (quasiment) identique entre une paire quelconque de nœuds
– Modèle de communication 1-port
– Liens de communication bidirectionnels (full-duplex)
●
Coût d’échange d’un mot (word) de taille m: t
s+ m T
w– ts: temps de démarrage (startup)
– tw: temps de transfert par mot
Communications point à point
● Communications bloquantes
– Le thread émetteur se bloque jusqu’à ce que le buffer soit utilisable:
– Après recopie dans un buffer,
– Ou après la fin de l’envoi
● Communications non bloquantes
– Le thread émetteur ne se bloque pas lors de l’envoi
– Réutilisation du buffer après vérification de la terminaison
Communications collectives
●
Ensemble d’opérations de communication impliquant un groupe de nœuds
●
Exemple: diffusion 1-to-n (Broadcast)
– Un processus diffuse un message de taille m à tous les autres
– Algorithme naïf:
● Le processus émetteur envoie à chacun des autres processus
● n-1 étapes
● Temps d’exécution: (n-1) . (ts + tw.m)
Communications collectives
●
Ensemble d’opérations de communication impliquant un groupe de nœuds
●
Exemple: diffusion 1-to-n (Broadcast)
– Un processus diffuse un message de taille m à tous les autres
– Autre algorithme :
● log n étapes
● Algo optimal dépend de la topologie
● Temps d’exécution: log n . (ts + tw.m)
Exercice : all-to-all
●
Diffusion all-to-all
– Tous les processus envoient un message de taille m à tous les autres
●
Exercice:
– Écrire l’algorithme
void all_to_all(int my_rank, message m, int m_size) { }
– Calculer le temps d’exécution
Exercice : all-to-all
Solution
void all_to_all(int my_rank, message m, int m_size) { for(int i=0; i<log(n); i++) {
int offset = 1<<i;
int direction = my_rank & offset;
int dest;
if(direction == 0) {
dest = my_rank + offset;
} else {
dest = my_rank - offset;
}
send(m, m_size, dest);
recv(&m[m_size], m_size, dest);
m_size *=2;
} }
) 1 (
log )
2 (
1 log
0
n m t n t
m t
t s w
n i
w i
Temps d’exécution: s
Autres communications collectives
●
Diffusion (Broadcast)
●
Distribution (Scatter)
●
Collecte (Gather)
●
Reduction (Reduce)
Autres communications collectives
Diffusion all-to-all
●
Diffusion 1 to n (Broadcast)
●
Diffusion n to n (AllToAll)
Autres communications collectives
Collecte all-to-all
●
Collecte 1 to n (Gather)
●
Collecte n to n (AllGather)
Autres communications collectives
Reduction all-to-all
●
Réduction 1 to n (Reduce)
●
Reduce n to n (AllReduce)
Comment découper une application
pour la rendre parallèle ?
Parallélisme de données
●
Parallélisation basée sur la distribution des données
– Distribution des données
– Owner computes
●
Pour un même tableau, plusieurs distributions possible
– Maximiser le rapport entre travail local et communication
Distribution de tableaux denses
●
Distribution d’un tableau 1D
– Par bloc, cyclique (élément par élément), bloc-cyclique
Distribution de tableaux denses
●
Distribution d’un tableau 2D
Exercice
●
Multiplication de matrices NxN
– Comment distribuer les matrices sur 4 processus ?
– Calculer l’occupation mémoire pour chaque processus
Exercice
Solution naïve
● Occupation mémoire
→ Problème de scalabilité en mémoire
● Communications : 0
2
. .
2
p N p
N N
Exercice
Autres solutions
● Occupation mémoire
→ Problème de scalabilité en mémoire
● Communications : phases
●
Algorithmes de Cannon, Fox, Snyder
2
.
3
p N
p
Parallélisme de tâches
●
Parallélisation basée sur la décomposition du calcul
● Décomposition en tâche
● Ordonnancement des tâches de calcul
●
Exemple: Choleski factorization
Data parallelism vs Task parallelism
●
Choleski parallélisé avec un #pragma omp parallel for
●
Choleski parallélisé avec des tâches
Comment répartir le travail de
manière équitable ?
Équilibrage de charge
●
But de la parallélisation:
● Réduire le temps d’exécution
● ~ équilibrer le temps d’exécution entre threads
→ Load balancing
Équilibrage de charge
●
3 niveaux de difficulté:
– Facile: cas régulier – n jobs de même coût
● Difficile: cas irrégulier – n jobs de coût différent, mais connu
● Très difficile: le coût des jobs est inconnu à l’avance
N jobs
Stencils, matrices denses, etc.
4 CPUs
N jobs 4 CPUs
Sparse MxV, etc.
Recherche, etc.
Répartition statique
●
Répartition statique du travail entre les threads
– Répartir les données de manière équitable
– Pas de communication pendant l’exécution
– En OpenMP: schedule(static)
●
Efficace pour les cas homogènes
●
Difficile dans certains cas
– Ressources de calcul hétérogènes
– Travail irrégulier
Répartition dynamique
exemple : recherche dans un arbre
●
Recherche d’une valeur dans un arbre/graphe
Répartition dynamique
exemple : recherche dans un arbre
●
Répartition statique
– Créer une tâche et l’affecter à un CPU inutilisé
Équilibrage sur 2 threads Équilibrage sur 4 threads
Tasks queues
Maître esclave
●
Une liste de tâches à exécuter
– Gérée par un thread manager (maître-esclave)
– Ou une structure de donnée protégée par un lock
● ex: schedule(dynamic) d’OpenMP
●
Problèmes
– Granularité des tâches
● Ne pas créer de tâches trop petites
– Pas de localité
– Contention sur le manager/lock
Tasks queues multiple
Vol de tâches
●
Une liste de tâches par thread
– Conserve la localité des données
– Pas de contention
– Quand liste locale vide: vol de tâche
● Qui voler ?
● Voler une « grosse » tâche
→ Deque (Double-ended queue)
7 dwarfs of HPC
A dwarf is an algorithmic method that captures a pattern of computation and communication.
● Dense Linear Algebra
● Sparse Linear Algebra
● Spectral Methods
● N-Body Methods
● Structured Grids
● Unstructured Grids
● MapReduce
Complete list: Asanovic, Krste, et al. "The landscape of parallel computing
Exercice : Mandelbrot
● L’application mandelbrot_seq.c calcule les éléments de l’ensemble de Mandelbrot
– Pour chaque “pixel”, un calcul est effectué
– La quantité de calcul nécessaire à chaque pixel donne une couleur
● Blanc ↔ beaucoup de calcul
● Noir ↔ très peu de calcul
● Modifiez l’application pour assurer l’équilibrage de charge
– De manière dynamique
– De manière statique