Télécharger la présentation
La présentation est en train de télécharger. S'il vous plaît, attendez
Publié parCharles Perin Modifié depuis plus de 11 années
1
Algorithmes parallèles auto-adaptatifs et applications
Daouda TRAORÉ Directeurs de thèse Jean-Louis ROCH & Denis TRYSTRAM Projet MOAIS Laboratoire d’Informatique de Grenoble (UMR 5217), France Vendredi 19 Décembre 2008 Merci, Bonjour, Aujourd’hui je vais vous présenter mon travail de thèse qui est sur les algorithmes parallèles auto-adaptatifs et applications. Ce travail a été financé par une bourse de coopération France-Mali qui a été gérée par EGIDE. Il a été effectué sous la direction conjointe de Messieurs Jean-Louis ROCH et Denis et Denis TRYSTRAM dans l’équipe Projet MOAIS.
2
Motivations Evolution des machines parallèles: de machines avec processeurs identiques vers: Grilles de calcul => ressources hétérogènes et dynamiques Systèmes multi-processus (Processeurs multi-cœurs, SMP, MPsoc) applications concurrentes sur une même unité => les cœurs apparaissent comme de vitesses variables Processeurs graphiques : GPUs + CPUs => hétérogénéité, fréquences et opérations différentes Questions: Est-ce qu’un algorithme parallèle peut fonctionner dans ce contexte? Avec quelles garanties de performance ? Sous quelles hypothèses? Les avancées dans le domaine des architectures parallèles au cours de ces dernières années, ont permis le développement considérable de nouvelles architectures. On est ainsi passé de machines avec processeurs identique vers des machines diversifiées. Comme les grilles de calcul; une grille de calcul est un ensemble de ressources interconnectées entre elles et géographiquement distantes, dans une grille les ressources sont hétérogènes et non fixes. Dans les systèmes multi-processus, plusieurs applications peuvent tourner en concurrence sur une même unité, ce qui fait que les unités peuvent avoir des charges différentes c’est-à-dire elles peuvent apparaitrent comme de vitesses variables. Dans les processeurs graphiques comme : les unités peuvent être de fréquences différentes et les opérations aussi peuvent différentes. Donc pour bénéficier pleinement de la puissance de ces nouvelles architectures les programmes parallèles doivent les exploiter efficacement. Alors la question qu’on se pose est : Est-ce qu’un algorithme pour processeurs identiques peut fonctionner dans ce contexte? Sous quelles hypothèses? Dans le passé, les algorithmes parallèles étaient conçus pour des systèmes dédiés. Il est difficile pour un utilisateur de choisir un algorithme adéquat pour un système donné, vu l’évolution continuelle des systèmes. En effet, un algorithme parallèle optimal pour une architecture dédiée n’est pas performant quand toutes les ressources de celle-ci ne sont pas disponibles. L’exploitation efficace de ces systèmes, nécessite le développement d’algorithmes capables de s’adapter automatiquement au contexte d’exécution. 2/52
3
Evolution de la programmation parallèle
Initialement: processeurs identiques (MPI) Aujourd’hui: Interfaces de haut-niveau permettant d’abstraire l’architecture. Grille Multi-coeurs, SMP GPU Google MapReduce : est un outil de programmation développé par Google en C++, dans lequel des calculs parallèles de données très grosses (> 1 terabyte) sont effectués. Cuda : Compute Unified Device Architecture. La Mémoire Virtuelle Partagée est une abstraction utilisée pour partager des données entre des processus sur des ordinateurs qui ne partagent pas physiquement leur mémoire. Son intérêt est de permettre l'utilisation d'un modèle de programmation qui a des avantages par rapport aux modèles basés sur l'échange de message. Les processus accèdent à la MVP par des lectures et des mises à jour sur ce qui leur semble être de la mémoire ordinaire à l'intérieur de leur espace d'adressage. Mais un système tournant en tâche de fond assure de manière transparente que les processus s'exécutant sur différents ordinateurs observent les mises à jour effectuées par d'autres processus. Le grand avantage de la MVP est d'épargner au programmeur la gestion de l'échange de messages quand il écrit une application qui en aurait besoin sans la MVP. On ne peut toutefois pas éviter complètement l'échange de message dans un système distribué, il faut bien-sûr que le système sous-jacent de la MVP envoie les mises à jours aux différents processeurs, chacun ayant une copie locale des données partagées récemment accédées pour une question de performance des accès. Cuda Google MapReduce OpenMP, Cilk++, intel TBB Athapascan/Kaapi 3/52
4
Construction d’algorithmes parallèles adaptatifs
Objectif de la thèse Construction d’algorithmes parallèles adaptatifs S’adaptent à la plate-forme d’exécution Inconscients du nombre de processeurs (en anglais, processor oblivious) Adaptation à la charge de la plate-forme Avec des garanties d’efficacité Temps d’exécution si possible optimal p/r aux ressources (dynamiquement) allouées Contexte: LIG / EP INRIA Moais: Thème sur la conception d’algorithmes adaptatifs [Roch&al gzip2001, TSI2005,...] Master ROCO D. Traoré 2005 : un algorithme de préfixe adaptatif (mais clairvoyant…) Un algorithme auto-adaptatif est un algorithme qui est capable de changer automatiquement son comportement en fonction de son contexte d‘exécution (données manipulées, plate-forme d’exécution, occupation des processeurs, …). Définition (algorithme auto-adaptatif) L’objectif de cette thèse est alors de spécifier et valider une technique permettant de construire des algorithmes adaptatifs. Ces algorithmes doivent s’adapter à la plate-forme d’exécution c’est être inconscients du nombre de processeurs de la plate-forme (c’est n’ayant aucune connaissance du nombre de processeurs), et s’adapter à la charge de la machine. On doit pouvoir donner aussi des garanties d’efficacité de ces algorithmes (avoir un temps d’exécution meilleur si possible optimal). On définit alors un algorithme auto-adaptatif comme un 4/52
5
Plan du mémoire et contributions
Introduction [objectifs et contributions, organisation] Programmation parallèle [notions] Algorithmes parallèles adaptatifs[définitions] Un algorithme adaptatif pour le calcul parallèle des préfixes [EUROPAR’06, CARI’06] Algorithmes adaptatifs de tri parallèle [RENPAR’08] Schéma générique des algorithmes parallèles adaptatifs [PDP’08, EUROPAR’08] Application du schéma à la librairie standard STL [EUROPAR’08, MSAS’08] Conclusion et perspectives Voici le plan de mon mémoire, qui a donné lieu à 6publications dont 4 internationales avec comité de lecture Dans cette partie, je vais vous présenter rapidement le plan du manuscrit et les contributions issues de cette thèse. Le manuscrit est organisé en 9 chapitres Le premier est un chapitre d’introduction, qui décrit le contexte de la thèse et l’organisation du document Les deux chapitres suivants présentent quelques notions de parallélisme et de l’adaptation Le chapitre 4 décrit le schéma adaptatif qui a été publié dans deux conférences internationales avec comité de lecture (PDP’08 et EUROPAR’08) Le chapitre 5 présente un nouvel algorithme adaptatif pour les préfixes qui été publié à EUROPAR’08 et un colloque africain sur la recherche en informatique avec comité de lecture Le chapitre 6 présente un nouvel algorithme optimal statique pour les préfixes Le chapitre 7 présente des algorithmes adaptatifs de tri qui été publié dans une conférence nationale avec comité de lecture (RENPAR’08) Le chapitre 8 présente les applications du schéma adaptatif à la librairie standard c++. Et le chapitre 9 termine le manuscrit avec les conclusion et perspectives 5/52
6
Plan de la présentation
Algorithmes pour processeurs identiques: illustration sur le calcul parallèle des préfixes Ordonnancement par vol de travail Schéma générique adaptatif Algorithme adaptatif pour le calcul parallèle des Préfixes Application du schéma à la STL Conclusion et perspectives Le plan de ma présentation est le suivant : D’abord dans la première partie je vais vous présenter quelques inconvénients des algorithmes pour processeurs identiques dans le contexte actuel. Je vais illustré ceux-ci sur le calcul parallèle des préfixes D’abord dans la deuxième partie je vais vous présenter l’ordonnancement par vol de travail qui est une technique permettant d’adapter des algorithmes. Puis dans la troisième partie je vais vous présenter le schéma générique adaptatif qui sera utilisé dans la suite pour adapter plusieurs algorithmes Ensuite dans la quatrième je vais vous présenter un algorithme adaptatif du calcul des préfixes, Dans la cinquième partie je vais vous présenter l’application du schéma adaptatif à la librairie standard c++ 6/52
7
Algorithmes pour processeurs identiques: illustration sur le calcul parallèle des préfixes
Calcul des préfixes Entrée : x0, x1, …, xn Sortie : p0, p1, ..., pn avec Applications : parallélisation de boucles, additions modulaires [Blelloch’89] Algorithme séquentiel : for(p[0]=x[0], i=1; i <= n; i++) p[i]=p[i-1]*x[i]; // n opérations Borne inférieure sur p processeurs identiques : Parallélisation optimale sur p processeurs identiques [Snir’86, Nicolau-Wang’96] [Fich’83] 7/52
8
Algorithmes pour processeurs identiques: illustration sur le calcul parallèle des préfixes
Un nouvel algorithme optimal pour le calcul des préfixes [chap. 3, pages 27-36] - Soit s et q le quotient et le reste de la division de n+1 par p+1: n+1 = s(p+1) + q Division du tableau initial en p+1 blocs de taille éventuellement différentes s+1 s+2 s-p+1 … q-1 blocs p-q+1 blocs p+1 blocs 8/52
9
Algorithmes pour processeurs identiques: illustration sur le calcul parallèle des préfixes
Algorithme statique en p+1 blocs s+1 … s+1 s+2 … s+2 s+1-p s+2-p p-1 1 p-1 étapes p-1 1 … p-1 1 … 9/52
10
Algorithmes pour processeurs identiques: illustration sur le calcul parallèle des préfixes
Analyse théorique du temps d’exécution de l’algorithme proposé et le nombre d’opérations vérifie : Remarque: Une variante donne un temps toujours optimal, mais n’a pas été programmée Théorème [chap. 3, page 30] Si 0 ≤ q ≤ 1 et (p+3)/2 ≤ q ≤ p, alors le temps d’exécution de l’algorithme (optimal) sur p processeurs identiques vérifie Théorème [chap. 3, pages 31 et 32] Si 2 ≤ q ≤ (p+3)/2, alors le temps d’exécution de l’algorithme à 1 de l’optimal sur p processeurs identiques vérifie 10/52
11
Algorithmes pour processeurs identiques: illustration sur le calcul parallèle des préfixes
Machine AMD Opteron 4 processeurs n grand, temps d’une opération très petit (temps d’addition de deux Doubles par exemple). Dans l’algorithme de Nicolau-Wang On a 2n/(p+1) synchronisations accélération 1 processeur taille temps n petit, temps d’une opération assez élevé taille 11/52
12
Algorithmes pour processeurs identiques: illustration sur le calcul parallèle des préfixes
Inconvénients de la parallélisation sur des processeurs identiques Nombre d’opérations : toujours le même si les p processeurs initialement prévus pour l’exécution ne sont pas disponibles. Exemple : si on suppose que Un seul processeur exécute l’algorithme parallèle Les autres étant mobilisés pour d’autres calculs => le nombre d’opérations effectuées par un seul processeur est L’algorithme optimal sur processeurs identiques n’est pas performant Si les processeurs sont de vitesses différentes (temps d’exécution final = temps d’exécution du processeur le plus lent) Si le temps de l’opération * est variable 12/52
13
Plan de la présentation
Algorithmes pour processeurs identiques: illustration sur le calcul parallèle des préfixes Ordonnancement par vol de travail Schéma générique adaptatif Algorithme adaptatif pour le calcul parallèle des Préfixes Application du schéma à la STL Conclusion et perspectives Dans cette partie, je vais vous présenter le schéma générique adaptatif qui est une technique permettant d’adapter des algorithmes. 13/52
14
Ordonnancement par vol de travail
Principe Suit le principe glouton : à tout instant où il existe une tâche prête non encore ordonnancée, tous les processeurs sont actifs. Algorithme distribué Chaque processeur gère localement une pile des tâches qu’il a rendues prêtes (créées, ou débloquées). steal tâches L’ordonnancement par vol de travail est une technique qui consiste à distribuer les tâches entre les processeurs. En fait une tâche est une suite d’instructions qui sera exécutée d’une manière séquentielle (c’est-à-dire instruction par instruction). Le principe de l’ordonnancement par vol de travail est le suivant : d’abord il suit le principe glouton : c’est-à-dire à tout moment si il y a une tâche qui est prête mais non ordonnancée, ça veut dire que tous les processeurs sont actifs C’est un algorithme Distribué : c’est dire que chaque processeur gère sa propre pile de tâches, qu’il rendues prêtes. La gestion locale de cette pile suit l’ordre séquentiel : la tâche qui est dépilée est toujours celle qui serait exécutée en premier parmi les tâches dans la pile, dans un ordonnancement séquentiel (Si c’est un ordre de type profondeur d’abord : la tâche la plus prioritaire est alors toujours en dernière position de la pile). Chaque fois qu’un processeur termine une tâche, si sa pile locale n’est pas vide, il prend la plus récente et l’exécute. Lorsque la pile d’un processeur devient vide, il devient inactif et il va choisir au hasard un ….dont la pile P0 P1 P2 Lorsqu’un processeur devient inactif, il choisit (au hasard) un processeur dont la pile en cours d’exécution contient une tâche prête et lui vole une tâche (la plus ancienne, en haut de la pile (FIFO). [Blelloch’90, ], [Leiserson & Kuszmaul 2001] 14/52
15
Modèle de coût associé au vol de travail (1/2)
Notations W = travail = le nombre d’opérations de l’algorithme parallèle sur 1 processeur Tp = la durée d’exécution de l’algorithme parallèle sur p processeurs D = la profondeur de l’algorithme parallèle (le nombre d’opérations sur le chemin critique) Pave = la vitesse moyenne des p processeurs : Théorème[Arora, Blumofe, Plaxton 02, Bender, Rabin 02] Avec une grande probabilité; Le temps d’exécution Tp d’un programme utilisant l’ordonnancement par vol de travail est majoré par : Le nombre de vols (réussis ou échoués) est inférieure à O(p.D) Dans cette partie je vais présenter le coût associé au vol de travail : D’abord je vous présente les notations : W = … L’ordonnancement par vol a été prouvé théoriquement prouvé efficace par Arora, Blumofe. Ils ont dmontré qu’avec une grande probabilité le temps… 15/52
16
Modèle de coût associé au vol de travail (2/2)
Efficacité de la parallélisation Wseq = travail de l’ algorithme séquentiel Tseq = temps d’exécution de l’algorithme séquentiel : Intérêt : Si W ≈ Wseq et D très petit, En général W ≥ c1Wseq, c1 mesure le surcoût dû à l’ordonnancement et au parallélisme. Surcoût de parallélisme Gestion des tâches : tâches empilées dans une pile Exemple : algorithme récursif, Grain fin : surcoût arithmétique (récursivité) Minimisation du surcoût d’ordonnancement Principe du travail d’abord[Frigo et al98, Roch01] Ce principe consiste à minimiser le surcoût de création de tâches de l’ordonnancement par vol de travail. Appels de création de tâches traduits en appel local de fonction séquentielle. Si on désigne par Wseq le travail de l’algorithme séquentiel : L’ordonnancement par vol devient très efficace si : Mais en général : Pour rendre l’ordonnancement par vol efficace : des techniques basées sur le principe du travail d’abord ont été mises en oeuvre 16/52
17
Bibliothèques implémentant le vol de travail
Cilk[ Frigo et al 98] Création de tâches : spawn Synchronisation : sync Architectures cibles : mémoires partagées Athapascan/Kaapi Athapascan [Roch et al, PACT 98] : interface applicative Basé sur le graphe de flot de données Création de tâches : Fork Création de données : Shared Architectures cibles : mémoires partagées et distribuées Kaapi [Gautier et al 07] : moteur exécutif, qui supporte Athapascan cilk A () { x = spawn C(); y = spawn B(); sync; return (x+y); } A (Shared_w<int> res) { shared<int> x; shared<int> y; Fork<C>()(x); Fork<B>()(y); Fork<M>()(x, y, res); } Plusieurs bibliothèques ont implémenté l’ord par vol de travail. Ici je vous présente deux de ces bibliothèques. Cilk est une bibliothèque qui été à MIT, et il est destiné pour les architectures à mémoires partagées. Athapascan/kaapi est destiné pour les machines à mémoire partagée et distribuée. 17/52
18
Ordonnancement par vol de travail : limite
Emulation séquentielle de l’algorithme parallèle Nombre d’opérations arithmétiques supérieur à celui de l’algorithme séquentiel Exemple : Calcul des préfixes, optimal avec n opérations ! - Entrée : x0, x1, …, xn - Sortie : p0, p1, ..., pn avec Un algorithme parallèle récursif (Diviser Pour Régner) : pref(n/2) final(n/2) … L’ordonnancement est efficace côté synchronisation avec l’utilisation du principe de travail d’abord, mais il devient pour certains types d’algorithmes. En fait dans le principe du vol de travail c’est l’émulation séquentielle de l’algorithme parallèle qui est exécutée; ce qui peut introduire des surcoûts arithmétiques. Par exemple, prenons l’exemple sur le calcul des préfixes. L’algorithme récursif peut être exécuté par vol de travail. W(n) = 2W(n/2) + n/2 = (1/2) n*log(n) => l’émulation séquentielle de l’algorithme parallèle fait plus d’opérations que l’algorithme séquentiel optimal ! 18/52
19
Plan de la présentation
Algorithmes pour processeurs identiques: illustration sur le calcul parallèle des préfixes Ordonnancement par vol de travail Schéma générique adaptatif Algorithme adaptatif pour le calcul parallèle des Préfixes Application du schéma à la STL Conclusion et perspectives Dans cette partie, je vais vous présenter le schéma générique adaptatif qui est une technique permettant d’adapter des algorithmes. 19/52
20
Schéma générique adaptatif
Ordonnancement par vol de travail: amélioration Principe de base [Roch&al TSI 2005] Remplacer l’émulation séquentielle de l’algorithme parallèle par un « vrai » algorithme séquentiel plus efficace. =>Utiliser le couplage de deux algorithmes : Un séquentiel: qui minimise le travail (nombre d’opérations) W Un parallèle: qui minimise la profondeur parallèle D Points clefs: À tout instant, chaque processus actif exécute un algorithme séquentiel, mais peut être volé par un processus inactif Un processus « suit » l’algorithme séquentiel (optimal) Le schéma générique adaptatif est basé sur un ordonnancement par vol travail amélioré. C’est-à-dire on remplace l’émulation séquentielle parallèle par un vrai algorithme séquentiel plus efficace. 20/52
21
Couplage adaptatif de deux algorithmes
Un processeur occupé a une tâche et l’exécute avec un algorithme séquentiel Ps T0.Run_seq() Principe : l’algorithme séquentiel est toujours exécuté par un processeur occupé 21/52
22
Couplage adaptatif de deux algorithmes
Un processeur devient libre et exécute une opération d’extraction de travail chez un processeur actif sans l’interrompre. Ps T0.Run_seq() steal Pv Principe : un processeur exécute toujours l’algorithme séquentiel, dès qu’un devient libre (c’est un co-processeur qui vient accélérer le travail de travail de l’algorithme séquentiel). 21/52
23
Couplage adaptatif de deux algorithmes
Un processeur devient libre et exécute une opération d’extraction de travail chez un processeur actif (victime) sans l’interrompre. Ps T0.Run_seq() Pv T’0.Run_seq() 21/52
24
Couplage adaptatif de deux algorithmes
La victime a fini sa tâche et préempte son voleur Ps Prempts Pv T’0.Run_seq() 21/52
25
Couplage adaptatif de deux algorithmes
La victime effectue un saut (jump) sur le travail déjà fait par le voleur, le voleur finalise éventuellement ses calculs grâce aux résultats de la victime. Ps Ps jump T0.Run_seq() gets Pv La victime va continuer séquentiellement sur le travail (l’algorithme séquentiel est toujours exécuté) T’0.Finalize 21/52
26
Couplage adaptatif : Amortissement des synchronisations (extraction séquentielle du travail)
A la fois les processeurs victime et voleur peuvent modifier les informations sur le travail en cours de traitement Nécessité de se synchroniser ( pour la cohérence des données) Côté victime Côté voleur work extract_seq() { lock(); //verrouiller ws = NextWorkSeq(); unlock(); //déverrouiller return ws; } work extract_par() { //Micro-loop lock(); //verrouiller wv = WorkToSteal(); unlock(); //déverrouiller return wv; } Le processeur exécute une boucle séquentielle, extrayant à chaque itération une séquence de k instructions (nano-loop). Si aucun vol n’a eu lieu pendant le calcul (séquentiel), alors son travail arithmétique est égal à Wseq de l’algorithme séquentiel (pas spawn/fork/copy ) . En choisissant k = Profondeur(Wrest ), cela ne fait pas augmenter la profondeur de l’algorithme parallèle, et fait au plus O(W / D ) opérations atomiques . Exemple: l’algorithme for_each de la librairie standard C++ Run_seq() { While((ws= extract_seq())≠Ø) { local_run(ws) // Nano-loop } Côté victime - Si taille(ws) est petite => surcoût élévé. - Choix de taille (ws) : taille (ws) = profondeur (wrest); => travail arithmétique ≈ Wseq 22/52
27
Couplage adaptatif : Amortissement des synchronisations (extraction séquentielle du travail)
Exemple : transform STL : boucle avec n calculs indépendants ni=l-fi f1 f2 l alog(n1) alog(n2) Machine utilisée : AMD Opteron Opteron 875 2,2 Ghz, Compilateur gcc, option –O2 Le processeur exécute une boucle séquentielle, extrayant à chaque itération une séquence de k instructions (nano-loop). Si aucun vol n’a eu lieu pendant le calcul (séquentiel), alors son travail arithmétique est égal à Wseq de l’algorithme séquentiel (pas spawn/fork/copy ) . En choisissant k = Profondeur(Wrest ), cela ne fait pas augmenter la profondeur de l’algorithme parallèle, et fait au plus O(W / D ) opérations atomiques . Exemple: l’algorithme for_each de la librairie standard C++ Temps[s] taille 23/52
28
Schéma adaptatif : Amortissement du surcoût arithmétique
Pour Certains d’algorithmes: Wseq n’est pas connu d’avance W > Wseq Exemple: algorithme find_if qui permet de trouver le premier élément d’une séquence vérifiant un predicat P0 P1 P2 P3 position ou se trouve l’élément Le temps séquentiel de l’algorithme est Tseq = 2 Le temps final de l’algorithme parallèle est le temps final du processeur ayant terminé le dernier. Donc T4 = 6 24/52
29
Schéma adaptatif : Amortissement du surcoût arithmétique
Pour s’adapter : division dynamique du travail global en des étapes (Macro-loop [Danjean, Gillard, Guelton, Roch, Roche, PASCO’07]), avec synchronisation après chaque pas schéma de type algorithme de Floyd n_cur elts n_cur / log(n_cur) Exemple : find_if Chaque intervalle (macro-étape) est un ensemble de calculs pouvant être effectués en parallèle The choose of the current step size is function of the size of remaining computation done. Papier de Beaumont, Nicolas Maillard et Jean Louis Roch à citer. P0, P1, P2 P0, P1, P2 P0, P1, P2 B1 B2 B3 25/52
30
Schéma adaptatif : Amortissement du surcoût arithmétique
Exemple : find_if STL Comparaison avec find_if parallèle MPTL [Baertschiger 06] Machine utilisée : AMD Opteron (16 cœurs); Données : doubles; Taille tableau : 106; Position élément : 105; Temps STL : 3,60 s; Temps prédicat ≈ 36μ Accélération inférieure à 1 26/52
31
Schéma adaptatif : Amortissement du surcoût arithmétique
Exemple : find_if STL Accélération par rapport au temps STL en fonction de la position où se trouve l’élément Machine utilisée : AMD Opteron (16 cœurs); Données : doubles; Taille tableau : 106; Temps prédicat ≈ 36μ accélération Nombre de processeurs 27/52
32
Schéma adaptatif : Analyse théorique
Trois niveaux de boucles utilisés dans l’algorithme du du schéma nano-loop => limite le surcoût de synchronisation micro-loop => permet le vol de travail et la préemption macro-loop => limite le surcoût arithmétique Analyse de la complexité de l’algorithme du schéma Théorème [chap. 6, pages 89 et 90] Si le temps parallèle d’exécution d’un algorithme sur un nombre infini de processeurs fait (1+s)Wseq opérations avec s ≥ 0, alors avec une grande probabilité, 28/52
33
Spécification et implantation du Schéma Interface C++ sur Kaapi
Suit le schéma de l’algorithme adaptatif Classes à instancier : WorkAdapt, JumpWork, FinalizeWork Les fonctions à instancier : Fonctions Spécifications bool extract_seq() extrait une partie du travail local bool extract_par() appelée lors du vol (extraction du parallélisme void local_run() exécution séquentielle efficace void join(const WorkAdapt stolenwork) fusionne les résultats void jump(JumpWork* &) construit le travail à sauter void after_jump(const JumpWork* ) donne les informations sur le travail sauté bool extract_nexmacro_work() extrait la taille d’une macro-étape bool get_finalize_work (FinalizeWork*&) donne le travail à finaliser void get_main_result() retourne le résultat de la victime void get_thieft_result() retourne le résultat du voleur void must_jump() autorise le saut 29/52
34
Spécification et implantation du Schéma Interface C++ sur Kaapi
Pour construire un algorithme adaptatif, l’utilisateur remplit les fonctions nécessaires Class MyWorkAdapt : public WorkAdapt { … bool extract_seq() { …. } bool extract_par() { void local_run() { void join(const WorkAdapt stolenwork) { Lancement du moteur adaptatif sur le travail construit void MyalgoAdapt (… ) { MyWorkAdapt my_work = new MyWorkAdapt(….); adapt::run(my_work); 30/52
35
Spécification et implantation du schéma Gestion des vols
Implémentation « sans pile » du couplage séquentiel-parallèle Mais le parallélisme récursif sans surcoût peut rester géré par Kaapi avec sa pile Gestion des vols: Remplacer la pile distribuée de tâches créées par une liste distribuée de tâches volées Intérêt : peu de vols => peu de tâches insérées dans la liste; les surcoûts de création sont aussi limités. Gestion lors de la préemption : (b) après préemption de v1 v2 v3 v12 v11 w v31 w v1 v2 v12 v11 v3 (a) avant préemption de v1 v31 v12 31/52
36
Plan de la présentation
Algorithmes pour processeurs identiques: illustration sur le calcul parallèle des préfixes Ordonnancement par vol de travail Schéma générique adaptatif Algorithme adaptatif pour le calcul parallèle des Préfixes Application du schéma à la STL Conclusion et perspectives Dans cette partie, je vais vous présenter le schéma générique adaptatif qui est une technique permettant d’adapter des algorithmes. 32/52
37
Algorithme adaptatif du calcul parallèle des préfixes (1/7)
Calcul des préfixes Entrée : x0, x1, …, xn Sortie : p0, p1, ..., pn avec Algorithme séquentiel : for(p[0]=x[0], i=1; i <= n; i++) p[i]=p[i-1]*x[i]; // n opérations Borne inférieure sur p processeurs identiques : Parallélisation optimale sur p processeurs identiques [Snir’86, Nicolau-Wang’96] Ne sont pas adaptés si le temps de l’opération * varie ou si les processeurs sont à vitesse variable Parallélisation sur un nombre non borné de processeurs [Ladner-Fischer’80, Lin-Su’02] Peuvent être émulés par vol de travail mais effectuent plus de 2n opérations But : trouver un algorithme adaptatif qui se comporte optimalement [EUROPAR’2006, CARI’2006] [Fich’83] 33/52
38
Algorithme adaptatif du calcul parallèle des préfixes (2/7)
a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 Ps p1 p2 p3 pi=a0*…ai Steal request Ps Pv i=a4*…*ai a4 a5 a6 Pv a5 a6 pi=a0*…ai 1ère étape de la macro-loop 1 2 3 4 5 6 7 8 9 temps 34/52
39
Algorithme adaptatif du calcul parallèle des préfixes (2/7)
a1 a2 a3 a6 a7 a8 a9 a10 a11 a12 a13 Ps p1 p2 p3 pi=a0*…ai a6 preempt p3 Ps Pv i=a4*…*ai a4 a5 Pv a5 a6 pi=a0*…ai 1ère étape de la macro-loop 1 2 3 4 5 6 7 8 9 temps 34/52
40
Algorithme adaptatif du calcul parallèle des préfixes (2/7)
a1 a2 a3 a6 a7 a8 a9 a10 a11 a12 a13 Ps p1 p2 p3 jump p6 p7 p8 p9 pi=a0*…ai Steal request Ps Pv i=a10*…*ai i=a4*…*ai a4 a5 a10 a11 a12 Pv p4 p5 a4 a11 a12 pi=a0*…ai 1ère étape de la macro-loop 2ème étape de la macro-loop 1 2 3 4 5 6 7 8 9 temps 34/52
41
Algorithme adaptatif du calcul parallèle des préfixes (2/7)
a1 a2 a3 a6 a7 a8 a9 a13 Ps p1 p2 p3 jump p6 p7 p8 p9 pi=a0*…ai preempt p9 a12 Ps Pv i=a10*…*ai a4 a5 a10 a11 a12 Pv p4 p5 a11 a12 pi=a0*…ai 1ère étape de la macro-loop 2ème étape de la macro-loop 1 2 3 4 5 6 7 8 9 temps 34/52
42
Algorithme adaptatif du calcul parallèle des préfixes (2/7)
a1 a2 a3 a6 a7 a8 a9 a12 a13 Ps p1 p2 p3 jump p6 p7 p8 p9 jump p12 p13 pi=a0*…ai T2 = 9 temps optimal = 9 Ps Pv i=a10*…*ai a4 a5 a10 a11 Pv p4 p5 p10 p11 a11 pi=a0*…ai 1ère étape de la macro-loop 2ème étape de la macro-loop 3ème étape de la macro-loop 1 2 3 4 5 6 7 8 9 temps 34/52
43
Algorithme adaptatif du calcul parallèle des préfixes (3/7)
Analyse théorique du temps d’exécution Théorème [chap. 4, pages 53 et 54] Le temps Tp sur p processeurs du calcul n+1 préfixes par l’algorithme adaptatif vérifie Avec une grande probabilité : 35/52
44
Algorithme adaptatif du calcul parallèle des préfixes (4/7): validation expérimentale
Taille des données : n=3.105, temps d’une opération ≈ 1ms accélération Nombre de processeurs Nombre de processeurs Machine Itanium-2 (8 cœurs) Machine AMD Opteron (16 cœurs) 36/52
45
Algorithme adaptatif du calcul parallèle des préfixes (5/7): validation expérimentale
Taille des données : n= 108, temps d’une opération = addition de deux doubles Temps d’exécution Nombre de processeurs Machine Itanium-2 (8 cœurs) Machine AMD Opteron (16 cœurs) 37/52
46
Algorithme adaptatif du calcul parallèle des préfixes (6/7): validation expérimentale
Taille des données : n= 104, temps d’une opération ≈ 2ms processeur fréquence 1 1760 Mhz 2 550 Mhz 3 1100 Mhz 4 1650 Mhz 5 660 Mhz 6 440 Mhz 7 1320 Mhz 8 880 Mhz 9 10 Temps [s] Nombre de processeurs [Simulateur CpuBurning /Cérin] Dix Machines de fréquences différentes AMD Opteron 38/52
47
Algorithme adaptatif du calcul parallèle des préfixes (7/7): validation expérimentale
Taille des données : n= , temps d’une opération ≈ 1ms Nombre de processeurs accélération 8 Machines distribuées AMD Opteron [accès des données paginé via mmap] 39/52
48
Plan de la présentation
Algorithmes pour processeurs identiques: illustration sur le calcul parallèle des préfixes Ordonnancement par vol de travail Schéma générique adaptatif Algorithme adaptatif pour le calcul parallèle des Préfixes Application du schéma à la STL Conclusion et perspectives Dans cette partie, je vais vous présenter le schéma générique adaptatif qui est une technique permettant d’adapter des algorithmes. 40/52
49
Applications du schéma à la librairie standard C++
La librairie STL (Standard Template Library) : Fournit : conteneurs, algorithmes, itérateurs Avantage : généricité Parallélisation de la STL PSTL (Parallel Standard Template Library) [Johnson et al 97] STAPL (Standard Adaptive Parallel Libary) [Thomas et al 88 ] MPTL (Multi-Processing Template Library) [Baertschiger 06 ] MCSTL (Multi-Core Standard Template Library) [Singler et al 07 ] Intel TBB (Thread Building Blocks) [Reinders 07] PaSTeL [Saule & Videau, RENPAR’08] KASTL (Kaapi Adaptive Standard Template Library) Implémenté sur le noyau exécutif kaapi Basé le schéma adaptatif La librairie STL (Standard Template Library) fournit Un ensemble de classes : conteneurs (list, vectors, deque, …) Des algorithmes : manipule le contenu des conteneurs (sort, partial_sum, …) Des itérateurs : permet parcourir et accéder aux données des conteneurs Avantage de la STL : généricité Parallélisation de la STL PSTL [Johnson et al 97] : conteneurs de classes distribués, non adaptée sur des plate-formes hétérogènes et dynamique STAPL [Thomas et al 88 ] : basée sur les techniques de combinaison et sélection d’algorithmes. Tous les algorithmes STL ne sont pas implémentés MPTL [Baertschiger 06 ] : n’implémente pas les algorithmes parallèles complexes MCSTL [Singler et al 07 ] : quelques algorithmes implémentés (ex : unique_copy) ne bénéficient pas encore de la parallélisation dynamique Intel TBB [Reinders 07] : Basé sur le vol de travail. Surcoûts arithmétiques liés à quelques algorithmes (ex : partial_sum) KASTEL (Kaapi Adaptive Standard Template Librairy) Implémenté sur le noyau exécutif kaapi Basé le schéma adaptatif : parallélisation adaptative et optimale des algorithmes 41/52
50
Applications du schéma à la librairie standard C++
Classification des algorithmes de la STL Classe Algorithmes implémentés Algorithmes sans fusion de résultats copy, copy_bacward, fill, fill_n, for_each, generate, generate_n, replace, replace_if, replace_copy, replace_copy_if, swap_ranges, transform Algorithmes avec fusion de résultats count, count_if, accumulate, inner_product, partial_difference Algorithmes avec terminaison anticipée find, find_if, find_end, find_first_of, adjacent_find, search_n Algorithmes avec surcoûts de parallélisme partial_sum, remove_copy_if, unique_copy Algorithmes de partition et de tri merge, stable_sort, partition, sort 42/52
51
Applications du schéma à la librairie standard C++
Algorithmes sans fusion de résultats Fonctions : extract_seq, extract_par, local_run (1) Algorithmes avec fusion de résultats Fonctions : (1) et join, jump (2) Algorithmes avec terminaison anticipée Fonctions : (2) et extract_nextmacro_work (3) Algorithmes avec surcoûts de parallélisme Fonction et classe : (3) et la classe FinalizeWork 43/52
52
Applications du schéma à la librairie standard C++: partition
« Partition »: primitive de base dans un tri de type « quicksort » Soit un tableau T[0..n], et un élément quelconque appelé pivot pris dans le tableau. Le but de l’algorithme de partition est d’arriver à la situation suivante : T[i] < pivot pour i appartenant à [0..k[ T[i] >= pivot pour j appartenant à [k..n[ Exemple : soit T = [10, 5, 2, 8, 20, 6, 32, 3, 7 ] et pivot = 8; T_partionné = [7,5,2,3,6, 20, 32, 8,10] 44/52
53
Applications du schéma à la librairie standard C++: partition adaptative
Tableau initial P1 45/52
54
Applications du schéma à la librairie standard C++: partition adaptative
Initialement P1 commence le calcul P1 45/52
55
Applications du schéma à la librairie standard C++: partition adaptative
P2 vol du travail chez P1 P1 P2 steal 45/52
56
Applications du schéma à la librairie standard C++: partition adaptative
P1 et P2 font la partition dans leurs intervalles respectifs P1 P2 45/52
57
Applications du schéma à la librairie standard C++: partition adaptative
P3 vol du travail chez P1 P1 steal P3 45/52
58
Applications du schéma à la librairie standard C++: partition adaptative
Les trois processeurs font la partition dans leurs intervalles respectifs P1 P2 P3 45/52
59
Applications du schéma à la librairie standard C++: partition adaptative
P4 vol du travail chez P2 P2 P4 steal 45/52
60
Applications du schéma à la librairie standard C++: partition adaptative
Les quatre processeurs font la partition dans leurs intervalles respectifs P1 P2 P3 P4 45/52
61
Applications du schéma à la librairie standard C++: partition adaptative
Les quatre processeurs font la partition dans leurs intervalles respectifs P1 P2 P3 P4 45/52
62
Applications du schéma à la librairie standard C++: partition adaptative
Les quatre processeurs font la partition dans leurs intervalles respectifs P1 P2 P3 P4 45/52
63
Applications du schéma à la librairie standard C++: partition adaptative
Les quatre processeurs font la partition dans leurs intervalles respectifs P1 P2 P3 P4 45/52
64
Applications du schéma à la librairie standard C++: partition adaptative
Les quatre processeurs font la partition dans leurs intervalles respectifs P1 P2 P3 P4 45/52
65
Applications du schéma à la librairie standard C++: partition adaptative
P1 a fini sa partie droite et préempte P3 P1 P2 préemption préemption P3 P4 45/52
66
Applications du schéma à la librairie standard C++: partition adaptative
P1 a fini sa partie droite et préempte P3 P1 P2 P4 45/52
67
Applications du schéma à la librairie standard C++: partition adaptative
Les processeurs continuent les calculs en parallèle P1 P2 P4 45/52
68
Applications du schéma à la librairie standard C++: partition adaptative
P1 a fini sa partie droite et préempte P2 P1 préemption préemption P2 P4 45/52
69
Applications du schéma à la librairie standard C++: partition adaptative
P1 a fini sa partie droite et préempte P2 P1 P4 45/52
70
Applications du schéma à la librairie standard C++: partition adaptative
P1 a fini sa partie droite et préempte P4 P1 préemption préemption P4 45/52
71
Applications du schéma à la librairie standard C++: partition adaptative
P1 a fini sa partie droite P1 45/52
72
Applications du schéma à la librairie standard C++: partition adaptative
Réarrangement des blocs non terminés P1 Réarrangement des blocs mal placés Tous les éléments qui sont dans cette partie sont supérieurs au pivot 45/52
73
Applications du schéma à la librairie standard C++ : partition adaptative
Réarrangement des blocs non terminés P1 Tous les éléments qui sont dans cette partie sont inférieurs au pivot Tous les éléments qui sont dans cette partie sont supérieurs au pivot Appel à partition adaptive sur ce intervalle 45/52
74
Applications du schéma à la librairie standard C++ : validations expérimentales
sort Machine : Opteron (16 cœurs ) Données : Doubles Taille : 108 Temps [s] Nombre de processeurs 46/52
75
Applications du schéma à la librairie standard C++ : validation expérimentales
unique_copy : supprime dans une séquence des éléments contigus égaux Exemple : 1 2 3 10 15 => 1 2 3 10 15 6 Machine : Opteron (16 cœurs ) Données : Doubles Taille : 108 Temps [s] Nombre de processeurs 47/52
76
Applications du schéma à la librairie standard C++ : validation expérimentales
partial_sum : identique au calcul des préfixes Machine : Opteron (16 cœurs ) Données : Doubles Taille : 3.105 2n/p Temps [s] 2n/(p+1) Nombre de processeurs 48/52
77
Applications du schéma à la librairie standard C++ : validations expérimentales
merge 8 processeurs Machine : Opteron (16 cœurs ) Données : Doubles accélération taille 49/52
78
Plan de la présentation
Algorithmes pour processeurs identiques: illustration sur le calcul parallèle des préfixes Ordonnancement par vol de travail Schéma générique adaptatif Algorithme adaptatif pour le calcul parallèle des Préfixes Application du schéma à la STL Conclusion et perspectives Dans cette partie, je vais vous présenter le schéma générique adaptatif qui est une technique permettant d’adapter des algorithmes. 50/52
79
Conclusion Spécification d’un schéma générique qui permet de développer des programmes parallèles adaptatifs Garanties théoriques prouvées Interface C++ sur Kaapi développée Validation expérimentales sur plusieurs exemples Calcul parallèle des préfixes Fusion de listes triées, partition, tri par fusion et tri introspectif Algorithmes de la STL : unique_copy, remove_copy_if, transform, accumulate, …. Bonnes performances expérimentales obtenues par rapport à d’autres algorithmes implantés dans d’autres librairies (MCSTL, TBB, SWARM) 51/52
80
Perspectives Implémenter le schéma sur d’autres bibliothèques
Optimisation de l’interface développée Supprimer les verrous : important pour un travail de petite taille Expérimenter et améliorer en contexte distribué (calcul automatique des seuils) Implémenter le schéma sur d’autres bibliothèques Comme : Cilk, Cilk++, intel Tbb Comparer les performances Avoir des algorithmes caches et processeurs inconscients (vrai pour plusieurs algorithmes (préfixe, partition, …), mais reste sort adaptatif?) Utilisation pour des applications de simulations 3D (SOFA, Everton) -> ressources hétérogènes: CPU/GPU [Soares et al 07] 52/52
81
MERCI DE VOTRE ATTENTTION!
QUESTIONS ?
Présentations similaires
© 2024 SlidePlayer.fr Inc.
All rights reserved.