WOW !! MUCH LOVE ! SO WORLD PEACE !
Fond bitcoin pour l'amélioration du site: 1memzGeKS7CB3ECNkzSn2qHwxU6NZoJ8o
  Dogecoin (tips/pourboires): DCLoo9Dd4qECqpMLurdgGnaoqbftj16Nvp


Home | Publier un mémoire | Une page au hasard

 > 

Environnements de grappes de calcul intensif sur réseaux d'entreprise: déploiement, exploitation et performances

( Télécharger le fichier original )
par Franklin TCHAKOUNTE
Université de Ngaoundéré - Master en Systèmes et Logiciels en Environnements Distribués 2010
  

Disponible en mode multipage

Bitcoin is a swarm of cyber hornets serving the goddess of wisdom, feeding on the fire of truth, exponentially growing ever smarter, faster, and stronger behind a wall of encrypted energy

UNIVERSITE DE NGAOUNDERE

Faculté des Sciences

Département de Mathématiques et Informatique

MEMOIRE DE MASTER

Spécialité:

SYSTEMES ET LOGICIELS EN ENVIRONNEMENTS
DISTRIBUES

Présenté par:

Franklin TCHAKOUNTE

Sur le sujet :

ENVIRONNEMENTS DE GRAPPES DE CALCUL INTENSIF
SUR RESEAUX D'ENTREPRISE: DEPLOIEMENT,
EXPLOITATION ET PERFORMANCES

Directeur du mémoire : Pr TAYOU
Encadreur: Dr Jean Michel NLONG II

DEDIDACES

Je dédie ce travail en premier lieu au Dieu tout Puissant qui jusqu'aujourd'hui m'a donné le souffle
de vie.

En second lieu :

AMon père TCHAKOUNTE Elie. Ma mère NGOUNDJIO Elisabeth. Mes frères et soeur.

REMERCIEMENTS

CEtte uvre a vu le jour grace au concours de plusieurs personnes.

Je saisi cette occasion pour exprimer mes sincères remerciements à tous ceux qui, de près comme

de loin, ont contribué à la mise en uvre de ce mémoire.

J'adresse ma profonde reconnaissance au Docteur Jean Michel NLONG II , qui m'a donné un sens de travail plus sérieux et qui, une fois de plus a bien voulu sacrifier ses préoccupations importantes en ne ménageant aucun effort pour suivre inlassablement ce travail. Il a été pour moi comme un parent qui sanctionne son enfant quand il faut pour le remettre sur le droit chemin.

Je remercie les membres du jury qui ont bien voulu accepter d'évaluer ce travail.

J'adresse mes remerciements aux enseignants du département d'Informatique et Mathématiques de l'Université de Ngaoundéré. dont la volonté et la moralité infaillibles témoignent du chemin exemplaire à suivre par toute la communauté scientifique.

Je n'oublie pas mes camarades de promotion, ensemble, nous avons constitué une véritable famille dans laquelle la volonté de travailler en équipe m'a permis de surmonter les obstacles rencontrés.

Je saisi cette occasion pour dire particulièrement merci à une très chère amie DASSI TCHOMTE Naomi, à ma soeur SAYOU NYASSI Flavienne, à mon frère SIME NYASSI Virgile, à l'AEE-NDE , à la congrégation des Témoins de JEHOVAH de DANG, à la famille DASSI de Yaoundé-Ekounou et à mes très chers potes Urbain et Patrick qui m'ont toujours et de très près soutenu dans les moments bons comme mauvais.

Je dis merci à toute ma famille, mes amis et ceux dont les noms ne figurent pas dans ce mémoire, mais qui ont tous constitué pour moi un soutien certain.

RESUME

Le calcul à haute performance(HPC) est de plus en plus utilisé dans les laboratoires de recherche. Le but est d'exécuter les applications le plus rapidement possible. De nos jours, les ordinateurs offrent de bonnes performances à des coûts raisonnables et les réseaux informatiques croissent rapidement. Une méthode consistant à fédérer plusieurs ressources de calcul ensemble pourrait fournir une puissance de calcul considérable pour exécuter l'application : on parle de calcul parallèle. Il faudrait donc trouver un moyen de subdiviser l'application en tâches, de trouver les processeurs surlesquels les exécuter et de trouver leur date de début d'exécution : on parle d'ordonnancement. Le problème d'ordonnancement des tâches d'un graphe est connu et de nombreux travaux ont déja été effectués sur ce sujet. La plupart des algorithmes d'ordonnancement de graphe de tâches visent des grappes homogènes constituées de ressources de calcul identiques reliées à travers un réseau homogène. Les noeuds et liens réseau d'une grappe peuvent avoir des caractéristiques différentes facilitant ainsi le fait qu'on puisse disposer facilement de plusieurs ressources. Dans ce cas on parle de grappe hétérogène. L'utilisation de ce type d'architecture rend l'ordonnancement des tâches difficile du fait de la synchronisation entre les différentes tâches d'une même application et des caractéristiques variables des composantes de calcul. Par exemple, deux noeuds de calcul peuvent disposer des processeurs de puissances différentes ainsi que leurs mémoires locales. Ainsi, le temps de gestion d'une reception d'un message par l'un est différent de celui de l'autre. Ils peuvent entraîner une baisse des performances de l'ensemble du système si les tâches sont ordonnançées d'une manière quelconque. Le problème d'ordonnancement sous ces conditions est un problème NP-Complet. Il est donc très difficile de trouver un algorithme qui le résoud en temps polynomial. Notre travail consiste à proposer une heuristique d'ordonnancement sur ce type d'architecture d'une part et de l'évaluer sur un exemple d'application parallèle d'autre part.

Mots clés : Application, graphe, tâche, ordonnancement, grappes, hétérogènes, homogène, calcul parallèle.

ABSTRACT

High performance computing are more needed in research and industry. It is objective is to execute an application in the fastest manner. Nowadays, it is easy for us to buy a personnal computer that have high performance more cheaper. A method by putting computing nodes together could provide considerable performance to compute a parallel application.This is the parallelism. It is therefore important to subdivide the application into tasks, to find the processors on which we will execute them and the date of their execution this is the problem of scheduling. This problem is well known and many works have been done on that subject. Most of them have been done on homogeonous clusters consisting of identical nodes of computing interconnected with an homogeonous network. On the other hands, the nodes and links can have no identical caracteristics. In this case, we speaking about heterogeonous clusters. Although they facilitate to have many resources of computing, heteregeonous clusters get tasks scheduling difficult in the sense that tasks have to communicate each others. For instance, two adjacents nodes with different performance will deal differently the reception of a message. So if tasks are scheduled randomly, the system can be affected in performance. The problem of scheduling in these conditions is NP-Complete. It is therefore too difficult to find a polynomial algorithm as a solution. Our work is to propose a heuristic of scheduling in heterogeonous clusters and evaluate it on an application.

Keywords Application, graph, task, scheduling, clusters, heterogeneous, homogeonous, parallelism.

Table des matières

Table des figures xi

Introduction générale 1

I CALCUL PARALLELE ET ARCHITECTURE DES GRAPPES 4

1 Calcul parallèle 4

1.1 Motivations et principes 4

1.2 Programmation parallèle 5

1.2.1 Objectifs de la programmation parallèle 5

1.2.2 Classes d'applications parallèles 6

1.2.3 Modèle de la programmation parallèle 6

2 Taxonomie des machines parallèles 8

2.1 Architecture SISD 8

2.2 Architecture MISD 9

2.3 Architecture SIMD 10

2.4 Architecture MIMD 11

2.4.1 Exemple d'application des quatre classes principales 14

3 Grappes d'ordinateurs 15

3.1 Origine et évolution de grappes 15

3.1.1 Les supercalculateurs 15

3.1.2 les réseaux de station de travail 15

3.1.3 Les grappes de PC 16

3.1.4 Les architectures actuelles 17

3.2 Caractéristiques des grappes 19

3.2.1 Accès aux ressources 19

3.2.2 Sécurité 20

3.2.3 Tolérances aux fautes 20

3.3 Infrastructures matérielles des grappes 20

3.3.1 Architectures matérielles des grappes 20

3.4 Infrastructures logicielles des grappes 21

4 Analyse des performances d'une architecture multiprocesseurs 22

4.1 Modèles de Calcul 22

4.1.1 Modèle à durée égale 22

4.1.2 Modèle de calcul parallèle avec des parties séquentielles 23

4.2 Un argument pour les architectures parallèles 25

4.2.1 Loi d'Amdahl 25

4.2.2 Loi de gustafson 26

II CONCEPTS D'ORDONNANCEMENT 28

1 Modélisation d'une application 28

1.1 Graphe de précédence 28

1.2 Graphe de flots de données 29

1.3 Graphe de tâches 32

2 Les Modèles classiques d'ordonnancement 33

2.1 Modèles à coût de communications nul 33

2.2 Modèle délai 34

2.3 Les modèles LogP et BSP 35

3 Modèles d'exécution et ordonnancement 36

3.1 Le modèle PRAM 36

3.2 Les modèles avec délai de communications 37

3.2.1 Modèle UET 38

3.2.2 Modèle UET-UCT 39

3.2.3 Modèle UET-LCT 39

3.2.4 Modèle SCT 41

3.3 Le modèle LogP 41

3.4 Le modèle BSP 42

III GRAPPES HETEROGENES et ORDONNANCEMENT 46

1 Eléments de coût 46

1.1 Les stations de travail 46

1.2 Les équipements réseau 46

1.2.1 Les commutateurs 47

1.2.2 Les concentrateurs 49

1.2.3 Les routeurs 49

1.3 Technologie réseau 49

1.4 Système d'exploitation et pile réseau 49

2 Proposition d'un modèle d'ordonnancement sur les grappes hétérogènes 51

2.1 Modélisation de l'architecture hétérogène 51

2.2 Graphe de tâches. 52

2.3 L'ordonnancement 52

2.4 Modéle des communications 52

2.5 Idée Générale 53

IV EVALUATION DU MODELE SUR UNE APPLICATION 54

1 Présentation de l'architecture de notre grappe 54

2 Calcul des caractéristiques des noeuds du graphe de grappe 55

2.1 Les surcoûts engendrés par la pile réseau relatifs à chaque station de travail . 55

2.2 Tableau récapitulatif et discussion 58

3 Calcul des caractéristiques des arcs du graphe de grappe 58

3.1 Evaluation des latences 58

3.2 Evaluation des débits des liens 61

3.2.1 Discussion 61

4 Programmation de l'application 61

4.1 Algorithme 61

4.2 Code 61

5 Ordonnancement sur la grappe 63

5.1 Résultats et discussion 64

Conclusion générale et perspectives 68

A Annexe 71

1 CONFIGURATION DE NOTRE GRAPPE 71

1.1 Configuration logicielle 71

1.1.1 OAR: gestionnaire de tâches 71

1.1.2 MPICH2 : bibliothèque de communications 73

1.1.3 Serveur NFS : Network file system 74

1.1.4 Serveur NIS : Network information service 75

2 Code séquentiel du produit d'une matrice par un vecteur 76

Bibliographie 77

LISTE DES ABBREVIATIONS

API : Application Program Interface ARP : Address Resolution Protocol BSP : Bulk Synchronous Parallel

CESDIS : Center of Excellence in Space Data and Information Sciences

CM : Connection Machine

CONDOR: Open Grid Computing COTS: Commodity Off The Shelf

CRAY: Supercomputer Company ( Name of the father of Supercomuting : Seymour Cray)

CRC : Cyclic Redondancy Control

CRCW : Concurrent Read Concurrent Write

CREW: Concurrent Read Exclusive Write EREW : Exclusive Read Exclusive Write FTP : File Transfer Protocol

GNU: GNU is Not Unix

HPC : High Personal Computing HTC : High Throughput Computing HTTP : Hypertext Transfer Protocol IBM: International Business Machine

IBM SP : International Business Machine Scalable Power

ICL DAP : International Computer LTds Distributed Array Processor

IPC : InterProcess Communication LAN : Local Area Network

LCT : Large Communication Time MAC : Media Access Control

MFLOPS : Mega Floatting Operations Per Second

MIMD : Multiple Instruction Multiple Data MISD : Multiple Instruction Single Data MPI : Message Passing Interface

MPICH : Message Passing Interface Chameleon MPMD : Mutiple Programs Multiple Data MVP : Model View Presenter

NEC : Network Enterprise Center

NFS : Network File System

NIS : Network Information System NOW : Network Of Workstations

NP : Non Polynomial

NUMA : Non Uniform Access

OAR: Resource Manager

OSI : Open Systems International

PC : Personal Computer

PRAM : Parallel Random Access Machine PVM : Parallel Virtual Machine

SAN: System Area Network

SCT : Small Communication Time SGI : Silicon Graphics Image

SISD : Single Instruction Single Data SIMD : Single Instruction Multiple Data SMP : Symmetric Multiprocessing SMTP : Simple Mail Transfer Protocol SPMD : Single Program Multiple data SSH : Secure Socket Shell

SSI : Single System Image

TFLOPS : Tera Floatting Operations Per Second UET : Unit Execution Time

UCT : Unit Communication Time

Table des figures

I.1 Architecture SISD 8

I.2 Architecture SIMD 9

I.3 Architecture MIMD 9

I.4 Modèle d'architecture SIMD 10

I.5 Les deux schémas SIMD 11

I.6 Architecture à mémoire partagée et Architecture de passage de messages 12

I.7 Un réseau de stations de travail 16

I.8 Une grappe de PC 16

I.9 Une grappe de grappes faiblement couplées 17

I.10 Une grappe multiplement câblée (avec des partitions) 18

I.11 Segments de programme 23

I.12 Modèle Amdahl 26

II.1 Exemple de Programme 29

II.2 Un graphe de précédence pour le programme. Les tâches sont représentées par des cercles et les arcs représentent les précédences. 30

II.3 Un graphe de flots de données pour le programme. Les tâches sont représentées par des

cercles. Les données à transférer dans un rectangle 31

II.4 Graphe de précédence G 31

II.5 Exemple de graphe de tâche du programme. Les chiffres en bleu représentent les coûts de chaque tâches. Ceux en noir représentent le volume des données à transférer d'une

tâche à l'autre par unité de temps. 32

II.6 Le modèle LogP 35

II.7 A gauche nous avons une représentation de l'ensemble des processeurs : P=8, L=6, g=4, o=2 et à droite l'activité de chaque processeur dans le temps. Le nombre montré pour chaque noeud est le temps auquel chaque processeur a reçu les données et peut

commencer à envoyer. 36

II.8 Le modèle PRAM pour le calcul parallèle 37

II.9 Exécution dans le modèle UET 39

II.10 Exécution dans le modèle UET-UCT sans et avec duplication 40

II.11 Exécution dans le modèle UET-LCT sans et avec duplication 40

II.12 Exécutions dans le modèle SCT sans et avec duplication 41

II.13 Exemple des paramètres LogP 42

II.14 Ordonnancement sous le modèle LogP 43

II.15 Schéma d'exécution dans le modèle BSP 44

III.1 Trame ethernet 47

III.2 Un message classique tel qu'il transite sur le réseau 51

IV.1 Notre grappe 55

IV.2 Courbe représentant l'accélération de l'algorithme parallèle 66

IV.3 Courbe représentant l'efficacité de l'algorithme parallèle 67

Introduction générale

D

E nos jours, aussi bien dans l'industrie que dans les laboratoires de recherche, la puissance de calcul est de plus en plus recherchée pour l'exécution d'applications de plus en plus gourmandes en ressources. Par exemple dans l'industrie cinématographique la puissance de calcul est employée

pour du calcul d'image. Dans des laboratoires de biologie, elle peut être employée pour des calculs d'affinité génétique entre différentes familles d'animaux. Dans tous les cas, l'objectif est d'exécuter les applications le plus rapidement possible, c'est-à-dire réduire le temps entre la soumission de l'application et l'obtention des résultats. C'est cela qu'on appelle le calcul à haute performance (HPC - High Performance Computing). Dans les années quatre-vingt à quatre-vingt dix, ce dernier s'appuyait sur des solutions coûteuses, basées sur des processeurs et des logiciels spécialisés, et destinés à un nombre limité de domaines tels que la météorologie, les phénomènes physiques, le nucléaire etc.. Cela exigeait que les centres de recherche disposent d'une puissance de calcul sans cesse croissante, qui n'était pas accessible financièrement à des organisations moyennes. L'évolution technologique permet aujourd'hui de disposer d'ordinateurs de bureau standard très performants à tel point qu'il est envisageable de construire à partir de ces machines des systèmes parallèles aussi rapides que les supercalculateurs dédiés type CRAY, IBM SP, NEC, Fujitsi. Chaque progression technologique ouvre l'horizon à de nouveaux besoins; et de nouvelles exigences. En effet, les applications deviennent de plus en plus gourmandes en temps de calcul et en espace mémoire.

Le calcul parallèle a toujours été une possibilité de répondre à cette demande de performances. Il consiste en l'exécution d'un traitement pouvant être partitionné en tâches élémentaires adaptées afin de pouvoir être réparties entre plusieurs processeurs opérant simultanément. L'objectif est de traiter des problèmes de grandes tailles plus rapidement que dans une exécution séquentielle. Les avantages du calcul parallèle sont nombreux. Du fait de contraintes physiques et technologiques, la puissance d'un ordinateur monoprocesseur reste limitée. En effet, il est difficile pour les fabricants de processeurs de produire des processeurs dont la puissance atteigne les centaines de MégaFlops1. La quantité de mémoire présente dans les ordinateurs monoprocesseurs est également limitée et il est par conséquent impossible d'exécuter certaines applications de grande taille sur de telles machines. Le calcul parallèle peut en revanche permettre de résoudre ce genre de problème. Ainsi, les machines parallèles actuelles utilisent des techniques originales de calcul parallèle pour maintenir l'activité des unités de calcul.

Les machines peuvent, par exemple disposer d'une mémoire partagée physique pour permettre aux différentes unités de calcul de coopérer. Dans d'autres cas, les machines parallèles sont construites

'million d'opérations ou calcul par seconde en virgule flottante

autour d'unités de calcul dotées de leur propre mémoire. Ces unités communiquent par échange de messages; on parle ici de machine à mémoire distribuée. Aujourd'hui, on assiste au développement rapide des machines parallèles de ce type: les grappes. Elles sont construites à partir de l'interconnexion de composants standards donc bon marché, comme les stations de travail ou les ordinateurs (PC). Ces architectures pouvant être constituées de plusieurs centaines de processeurs, offrent des performances potentiellement exceptionnelles pour un prix modeste. Avec l'avènement du logiciel libre et le coût assez bas des ordinateurs de bureau, la très forte demande en calcul haute performance (scientifique et technique) peut être satisfaite à un coût raisonnable. Les grappes de PC apparaissent donc comme une très bonne alternative aux moyens de calculs traditionnels. Cependant, leur exploitation reste très délicate et pose encore de très nombreux problèmes.

La programmation sur ce type de machines demande beaucoup plus d'efforts que l'écriture d'un programme séquentiel pour plusieurs raisons:

- Peu d'équipes sont capables de développer et de maîtriser l'environnement de grappe.

- l'hétérogénéité de la grappe au niveau des ressources de calcul (processeur) et au niveau des

capacités de communication (réseau) contraint l'utilisateur de monter lui même son système

afin d'adapter l'exécution des applications sur ce système.

- La programmation dépend fortement de la machine cible et de son support au parallélisme. Par exemple, les processeurs d'une machine parallèle peuvent avoir des propriétés distinctes, telles que le mode d'échange des données (mémoire partagée ou distribuée via un réseau d'interconnexion), de même que la cadence de son mode de fonctionnement.

L'environnement de grappes hétérogènes admet donc une complexité liée à l'application que l'on veut exécuter en termes de graphe de tâches (dépendances), à la topologie du système (communications entre les noeuds via le réseau), aux ressources disponibles dans le système (processeurs, mémoire). Il est donc capital de tenir en compte ces différents paramètres pour pouvoir exécuter efficacement une application sur une plate-forme hétérogène.

Il est question pour nous de proposer un algorithme d'ordonnancement efficace de tâches d'une application en tenant compte de ces éléments.

L'élaboration des applications parallèles

Dans l'informatique séquentielle, l'écriture d'une application consiste à choisir un algorithme qui résout un problème et de faire son analyse. Pour concevoir une application parallèle, nous devons d'abord choisir un algorithme qui résout le problème envisagé. Cet algorithme est alors partitionné en tâches lesquelles correspondent à des portions du code qui seront exécutées en séquentiel. Ensuite, le programme parallèle est conçu en attribuant à chaque tâche un processeur et une date d'exécution. La performance de l'application est mesurée alors par le temps d'exécution parallèle. Si une tâche a besoin des données produites par une autre tâche, il existe une relation de dépendance. Les tâches et leurs relations de dépendance sont représentées sous la forme d'un graphe, où les sommets correspondent aux tâches et les arcs aux relations de précédence entre elles. Ce graphe exprime le degré de parallélisme de l'algorithme et est nommé graphe de précédence ou de tâches. L'opération qui attribue aux tâches des dates d'exécution et des processeurs est dénommée ordonnancement, elle sera présentée en détail au chapitre 3.

Il est clair qu'il faut distinguer la phase d'extraction du parallélisme d'un algorithme de la phase d'exploitation de ce parallélisme. Dans un premier temps un graphe de précédence est construit, et ensuite un schéma d'ordonnancement est appliqué en fonction de l'architecture du modèle de machine. Or, pour certains problèmes, le graphe de précédence est construit au cours de l'exécution. Dans ce cas, les deux étapes ne peuvent pas être dissociées dans le temps.

Nous nous intéressons aux problèmes où le graphe de précédence est fourni de façon explicite avant le début de l'exécution (ordonnancement statique). Dans ces problèmes d'ordonnancement notre objectif est de minimiser le temps d'exécution total encore appelé makespan.

Problématique

La répartition des calculs et des données est l'un des problèmes majeurs à résoudre pour réaliser une application parallèle efficace. Il faut décider de la date et du lieu d'exécution des calculs du programme parallèle sur l'ensemble des ressources (processeur, mémoire..) de la machine. L'efficacité de l'exécution va dépendre de ces décisions. Dans ce mémoire, nous nous attachons à décrire le modèle de coût de notre grappe et de proposer une solution au problème d'ordonnancement de tâches d'une application sur une grappe hétérogène.

Organisation du travail

Ce document est divisé en quatre chapitres : le premier nous introduit à l'architecture des grappes et au calcul parallèle en présentant de manière concise les différents types d'architectures parallèles d'après la classification de Flynn et de l'évolution des grappes de PCs. Ce chapitre est l'occasion pour nous d'insister sur l'architecture de grappes hétérogènes notamment sur leurs caractéristiques matérielles, logicielles et sur l'hétérogénéité qui les rend plus complexes. Il parle également de la notion de programmation sur ces types d'architecture et de certains standards de programmation d'applications parallèles dont MPI qui nous intéresse. Ce standard est la cible d'un nombre impressionnant dans le monde et est doté des caractéristiques favorables aux grappes hétérogènes. Comment analyser les performances d'une application parallèle a été la question répondue après avoir présenté des postulats existants. La représentation d'une application parallèle en graphe de tâches, l'ordonnancement de ces dernières suivant les modèles de communication font l'objet du deuxième chapitre. L'étude des éléments définis aux chapitres précédents nous permet de formuler au chapitre 3 un modèle d'ordonnancement sur grappes hétérogènes en tenant compte de ses caractéristiques. Le chapitre 4 est la partie pratique de notre contribution car il expose l'implémentation de notre modèle en effectuant des évaluations sur un exemple. Nous concluons ensuite ce travail et apportons des perspectives pour la suite de nos recherches.

Chapitre I

CALCUL PARALLELE ET ARCHITECTURE

DES GRAPPES

D

Epuis les débuts de l'informatique s'est posée la question de résoudre rapidement des problèmes (le plus souvent numériques) coûteux en temps de calcul : simulations numériques, cryptographie, imagerie, S.G.B.D., etc. Pour résoudre plus rapidement un problème donné, une idée naturelle

consiste à faire coopérer simultanément plusieurs agents à sa résolution, qui travailleront donc en parallèle.

1 Calcul parallèle

1.1 Motivations et principes

La puissance des ordinateurs séquentiels augmentant de manière régulière (en gros, elle est multipliée par deux tous les dix-huit mois1), on pourrait croire qu'elles sera toujours suffisante, et que les machines parallèles (ordinateurs multiprocesseurs) sont inutiles. Plusieurs raisons contredisent cette tendance.

1. A mesure que la puissance des machines augmente, on introduit l'outil informatique dans des disciplines où il ne pouvait jusqu'alors pénétrer, et on cherche à intégrer de plus en plus de paramètres dans les modèles numériques : météorologie, synthèse et reconstruction d'images, simulations numériques, etc. Un certain nombre d'applications <sensibles> ont été classées <Grand Challenge> , et font l'objet de recherches intensives, tant au niveau du matériel que du logiciel. Elles sont également appelées < applications 3T >, parcequ'elles nécessitent pour leur exécution: - 1 Téra flops2 (floating operation per second);

- 1 Téra octets de mémoire centrale;

- 1 Téra octets par seconde de bande passante pour produire les résultats.

2. La vitesse de la lumière est (actuellement) une limitation intrinsèque à la vitesse des processeurs. Supposons en effet que l'on veuille construire une machine entièrement séquentielle disposant d'une puissance de 1 Tflops et de 1 To de mémoire. Soit d la distance maximale entre la mémoire

1Loi de Moore

21 Téra = 103Giga = 106Méga = 109Kilo = 1012.

et le micro-processeur. Cette distance doit pouvoir être parcourue 1012 fois par seconde à la vitesse de la lumière, c 3.108m.s-1,d'où

d = 3.108

1012

= 0,3mm.

L'ordinateur devrait donc tenir dans une sphère de 0,3 mm de rayon. Avec cette contrainte de distance, si l'on considère la mémoire comme une grille carrée de 106 x 106 octets, alors chaque octet doit occuper une cellule de 3Å de côté, c'est à dire la surface occupée par un petit atome. On ne tient ici pas compte de l'espace nécessaire à l'acheminement de l'information et de l'énergie, ainsi qu'à l'extraction de la chaleur.

Bien que la puissance et la capacité mémoire des ordinateurs ne cessent de croître, certains utilisateurs désirent toujours obtenir leurs résultats plus rapidement. D'autres souhaitent aussi faire tourner des simulations de plus grande précision en conservant un temps de calcul raisonnable. Le coût de fabrication d'un processeur toujours plus puissant croît exponentiellement avec la vitesse avec laquelle il peut faire les calculs. Par contre obtenir N processeurs ne représente qu'un coût N fois plus grand que celui d'un seul processeur. Le coût total de la machine parallèle (incluant le réseau d'interconnexion...) reste donc du même ordre. Le parallélisme consiste à utiliser plusieurs ressources disponibles (processeurs, mémoires, disques, etc.) pour qu'elles participent ensemble au calcul d'une application. En multipliant les ressources par N , un utilisateur peut espérer :

- calculer N fois plus vite,

- calculer des problèmes occupant N fois plus d'espace mémoire.

Le calcul parallèle est donc un moyen pour fournir de la haute puissance de calcul à un prix raisonnable en utilisant des ordinateurs personnels. Pourtant, cela ne suffit pas; il faudrait trouver une bonne méthode pour soumettre l'application aux différentes ressources présentes en vue de son exécution. Pour cela, il faut appliquer une bonne programmation de l'application en vue de bien répartir les données pour résoudre un problème de grande taille qui satureraient la mémoire d'un seul ordinateur ou même d'un supercalculateur.

Les applications parallèles sont une classe très importante d'applications concurrentes pour le calcul scientifique : elles visent à diminuer les temps d'exécution des calculs numériques intensifs, ou bien à répartir les données pour résoudre des problèmes de grande taille qui satureraient la mémoire d'un seul ordinateur ou même d'un seul supercalculateur. Cette section présente la classe des applications parallèles, puis elle se focalise sur deux technologies de programmation parallèle, à savoir les bibliothèques MPI et les systèmes de MVP.

1.2 Programmation parallèle

1.2.1 Objectifs de la programmation parallèle

La programmation parallèle s'est imposée dans le domaine du calcul scientifique, car son objectif est essentiellement la haute performance. La programmation parallèle vise :

- à répartir les tâches de calcul dans plusieurs processus sur plusieurs processeurs;

- à répartir les données des problèmes de grande taille qui satureraient la mémoire d'un seul ordinateur ou même d'un superordinateur;

- à recouvrir les calculs et les opérations d'entrées-sorties, afin de masquer leur latence.

Dans tous les cas, l'objectif de la programmation parallèle est de diminuer les temps d'exécution des calculs numériques intensifs. Cette propriété permet alors d'augmenter la précision des calculs (et donc la taille des données) tout en conservant des temps de calcul acceptables.

1.2.2 Classes d'applications parallèles

Programmation multi-threads ou multiprocessus. La programmation < multi-threads > est une méthode de programmation parallèle qui consiste à faire coopérer plusieurs threads au sein d'un même processus pour exécuter l'application : elle permet en particulier de recouvrir les calculs et les opérations d'entrées-sorties. Une autre approche est la programmation < multi-processus »3 : soit tous les processus de l'application sont issus du même code source (SPMD4), soit l'application est faite de plusieurs programmes (ou codes sources) différents (MPMD5). Dans le cas de la programmation multi-processus, les tâches de calcul sont le plus souvent réparties sur des ordinateurs qui ne partagent pas de mémoire commune. Or les processus doivent coopérer, donc s'échanger des données ou se synchroniser. Les communications entre les processus sont susceptibles de ralentir l'exécution d'une application parallèle multi-processus. Le ratio calcul/communications est le rapport entre le temps passé par les processus à faire des opérations de calcul et le temps qu'ils passent à communiquer. Plus ce ratio est faible et moins l'intérêt de la parallélisation est évident. C'est pourquoi on peut rarement augmenter indéfiniment le nombre de processus qui se répartissent les tâches de calcul car ils passent alors plus de temps à communiquer qu'à calculer et le temps global d'exécution de l'application augmente.

Applications statiques et applications dynamiques. Parmi les applications parallèles, on peut distinguer les applications statiques et les applications dynamiques.

Applications statiques. Dans une application statique, tous les processus sont lancés au moment du déploiement de l'application : l'utilisateur sait combien de processus composent l'application au début de son exécution et le nombre de processus reste le même tout au long de l'exécution. Applications dynamiques. Dans une application dynamique, il se peut qu'un ou plusieurs processus soient créés en cours d'exécution, ou bien soient terminés avant la fin de l'exécution de l'application. Cette création ou terminaison de processus en cours d'exécution se fait à l'initiative de l'application et les processus ajoutés doivent faire partie intégrante de l'application, au même titre que les processus lancés au moment du déploiement initial de l'application. Par exemple, un utilisateur qui lance par ailleurs un programme de visualisation ou d'analyse des traces de l'application en cours d'exécution ne permet pas de qualifier l'application de dynamique.

Actuellement, la plupart des applications de calcul scientifique sont statiques, car elles sont plus simples à programmer, et il existe peu de support pour les applications parallèles dynamiques.

1.2.3 Modèle de la programmation parallèle

Nous distinguons deux grandes classes de modèles de programmation parallèle :

- avec le parallélisme explicite, le programmeur fait l'effort de parallélisation de l'application : décomposition en sous-tâches, placement des tâches sur les processeurs, répartition et redistribution des données, communications (échange de données et synchronisation) entre les tâches, etc.;

- avec le parallélisme implicite, le travail de parallélisation de l'application est effectué par un compilateur (pour les langages parallèles), par un outil de parallélisation automatique, ou bien par une bibliothèque de fonctions déjà parallélisées.

3Les approches multi-threads et multi-processus ne sont pas incompatibles. 4Single Program, Multiple Data

5Multiple Program, Multiple Data.

Comme le programmeur est souvent le plus à même de décider comment le parallélisme peut être exploité pour un problème particulier, le parallélisme explicite donne en général de meilleures performances que la parallélisme implicite.

La programmation par passage de messages, celle par mémoire partagée et certains langages parallèles font partie de la classe du parallélisme explicite; les bibliothèques parallèles de haut niveau d'abstraction relèvent du parallélisme implicite, même si la frontière entre ces deux types de parallélisme n'est pas toujours très nette.

Passage de messages. La programmation par passage de messages consiste à faire coopérer les différentes tâches qui constituent l'application par l'envoi et la réception explicites de données, typées ou non. Le plus souvent, les environnements de programmation par passage de messages ( MPI (Message-Passing Interface) et PVM (Parallel Virtual Machine) ) offrent également des opérations de synchronisation simples (la < barrière >, qu'un processus ne peut franchir que lorsque tous les autres processus de l'application l'ont aussi atteinte), ainsi que des opérations < collectives >, telles que :

- envoyer une donnée à tout un groupe de processus en une seule opération (diffusion, ou Broad-

cast);

- effectuer une opération arithmétique simple (produit, somme, etc.) ou logique ( < et > , < ou > , etc.) sur des données détenues par tous les processus d'un groupe (opération de < réduction >, Reduce);

- regrouper dans un seul processus des données qui sont dispersées dans chaque processus d'un groupe (Gather);

- disperser des données situées dans un vecteur sur un processus vers les autres processus d'un groupe (Scatter).

Deux grands standards sont disponibles pour le passage de messages: Message Passing Interface (MPI) et Parallel Virtual Machine (PVM).

MPI est une API6 pour écrire des programmes parallèles portables. C'est une bibliothèque portable de programmation parallèle sur des ordinateurs distribués, hétérogènes (systèmes d'exploitation, architectures matérielles) et reliés en réseau. PVM est plus ancien, mais nous avons choisi de travailler avec MPI qui présente de nombreux avantages :

- MPI est une norme définie par le ' MPI Forum [29], soutenu par les milieux académiques et industriels;

- il existe un très grand nombre d'implémentations de MPI, tant académiques (gratuites ou non) qu'industrielles (IBM, Sun Microsystems, SGI, etc.), et qui sont portées sur de nombreuses plates-formes;

- MPI est toujours un sujet de recherche actif et fait l'objet de nombreux développements;

- MPI est très massivement utilisé dans les milieux scientifiques (physiciens, chimistes, etc.) pour le calcul numérique parallèle.

Ainsi, la programmation par passage de messages est un modèle d'assez bas niveau : le travail de parallélisation revient intégralement au programmeur.

Mémoire Partagée. Dans le modèle de programmation parallèle par mémoire partagée, les tâches qui constituent l'application coopèrent par l'écriture et la lecture dans une mémoire commune : ces opérations permettent d'échanger des données et de se synchroniser. Si les tâches sont les threads d'un même processus, alors ils peuvent lire et écrire dans l'espace d'adressage du processus. Si les tâches sont des processus au sein d'un même système d'exploitation, alors ils peuvent partager des segments

6Application Programming Interface.

de mémoire c'est le cas par exemple avec les IPC7, ou bien encore avec les systèmes à image unique (SSI8). Enfin, le mécanisme de < mémoire virtuellement partagée > (MVP) permet de programmer des systèmes à mémoire distribuée en utilisant le modèle de programmation parallèle par mémoire partagée un environnement de MVP donne l'illusion à des processus localisés sur des machines distribuées (avec des systèmes d'exploitation distincts) de partager un espace mémoire commun.

Dans ce modèle, la distribution des données est transparente et les communications entre les tâches de l'application parallèle sont implicites ce modèle est d'un peu plus haut niveau que celui de la programmation par passage de messages. Cependant, la programmation par mémoire partagée laisse encore le soin au programmeur de gérer lui-même la décomposition du problème en tâches de calcul, le placement de ces tâches, et la gestion de la localité des accès.

2 Taxonomie des machines parallèles

Pour ordonnancer finement une application parallèle, il est également nécessaire de bien identifier les paramètres clés qui reflètent les architectures de la machine parallèle surlesquelles on envisage d'exécuter des applications. Historiquement, l'une des premières classifications est celle proposée par Flynn [12] en 1966. Le système de classification de Flynn [12] est basé sur la notion de flots d'information. Il existe deux types de flots d'informations dans un processeur les instructions et les données [14]. Le flot d'instructions est défini comme la séquence d'instructions exécutée par l'unité de calcul. Le flot de données est défini comme le trafic de données échangé entre la mémoire et l'unité de calcul. Selon la classification de Flynn, les flots d'instructions ou de données peuvent être uniques ou multiples. L'architecture de l'ordinateur peut être classifiée en quatre catégories distinctes [14].

- Single-instruction single-data streams (SISD);

- Single-instruction multiple-data streams (SIMD);

- Multiple-instruction single-data streams (MISD);

- Multiple-instruction multiple-data streams (MIMD).

2.1 Architecture SISD

Les machines Von Neumann monoprocesseur conventionnelles sont classifiés comme les systèmes SISD. Les algorithmes pour les calculateurs SISD ne contiennent aucun parallélisme. La figure I.1 représente cette machine.

Figure I.1 - Architecture SISD

7InterProcess communication

8Single System Image, où un système d'exploitation unique couvre un ensemble d'ordinateurs distribués, tel que Kerrighed : http :// www.kerrighed.org/.

2.2 Architecture MISD

Dans la catégorie MISD, le même flot de données circule dans un vecteur linéaire de processeurs qui exécutent des flots d'instructions différentes. En pratique, il n'existe aucune machine construite sur ce modèle. Certains auteurs ont considérés les machines pipelines comme des exemples de machines MISD.

Les ordinateurs parallèles sont soit SIMD ou MIMD. Lorsqu'il ya seulement une unité de contrôle et lorsque tous les processeurs exécutent la même instruction de manière synchrone, la machine parallèle est classifiée comme SIMD. Dans la machine MIMD, chaque processeur a sa propre unité de contrôle et peut exécuter des instructions différentes sur des données différentes.

Les figures I.2 et I.3 représentent les machines SIMD et MIMD respectivement.

Figure I.2 - Architecture SIMD

Figure I.3 - Architecture MIMD

2.3 Architecture SIMD

Le modèle SIMD du calcul parallèle comprend deux parties : l'ordinateur frontal de style Von Neumann et un ensemble de processeurs comme montre la figure I.4. Le vecteur de processeurs est un ensemble d'éléments de calcul identiques synchronisés capables d'exécuter simultanément la même opération sur des données différentes. Chaque processeur dans le vecteur a une petite mémoire locale où résident les données distribuées lors du calcul parallèle. Le vecteur de processeurs est connecté au bus mémoire du frontal ainsi donc le frontal peut accéder aléatoirement aux mémoires locales des processeurs comme si c'était une autre mémoire.

Figure I.4 - Modèle d'architecture SIMD

Les processeurs opèrent de façon synchrone et une horloge globale est utilisée pour effectuer les opérations en mode <lockstep> c'est à dire qu'à chaque étape (top de l'horloge globale) tous les processeurs exécutent la même instruction, chacun sur une donnée différente. Dans ce système, soit les processeurs ne font rien, soit ils effectuent la même opération au même moment. Les processeurs <array> comme le ICL DAP (Distributed Array Processor) et les processeurs vectoriels pipelinés comme les CRAY 1, le CRAY 2 et le CYBER 205 font partie de la classe des calculateurs SIMD. Aussi, plus récemment, Maspar et CM (Connection Machine). Les machines SIMD sont particulièrement utiles pour traiter les problèmes à structure régulière où la même instruction s'applique à des sous-ensembles de données. Il y a deux schémas majeurs qui sont utilisés dans les machines SIMD (voir figure I.5).

Dans la première configuration, chaque processeur a sa mémoire locale. Les processeurs peuvent communiquer entre eux via le réseau d'interconnexion. Si le réseau d'interconnexion ne fournit pas une connexion directe entre une paire de processeurs donnée, alors cette paire pourra échanger les données via un processeur intermédiaire.

Dans la seconde configuration SIMD, les processeurs communiquent entre eux via un réseau d'interconnexion. Deux processeurs peuvent s'échanger les données par l'intermédiaire des modules de mémoire ou par un processeur intermédiaire.

Exemple : Addition de deux matrices A + B = C Soient deux matrices A et B d'ordre 2, et 4 processeurs. A11 + B11 = C11 ... A12 + B12 = C12

A21 + B21 = 1 ... A22 + B22 = 2

La même instruction est envoyée aux 4 processeurs (ajouter les 2 nombres) et tous les processeurs exécutent cette instruction simultanément. Un pas de temps suffit contre quatre sur une machine séquentielle.

Figure I.5 - Les deux schémas SIMD

Une instruction peut être simple (addition de 2 nombres) ou complexe (fusion de 2 listes). De la même façon les données peuvent être simples (un nombre) ou complexes (plusieurs nombres). Il peut parfois être nécessaire de limiter l'exécution de l'instruction a un sous ensemble des processeurs c'est à dire seulement certaines données ont besoin d'être traitées par cette instruction. Cette information peut être codée par un 11drapeau 11sur chaque processeur qui indique si :

1. le processeur est actif (exécute l'instruction)

2. le processeur est inactif (attend la prochaine instruction) 2.4 Architecture MIMD

C'est la classe la plus générale et la plus puissante de toute cette classification. Les architectures parallèles MIMD sont faites de plusieurs processeurs et de plusieurs modules de mémoires connectées via un moyen de communication. Elles sont subdivisées en deux catégories : La mémoire partagée et le passage de messages. La figure I.6 illustre l'architecture générale de ces deux catégories.

Figure I.6 - Architecture à mémoire partagée et Architecture de passage de messages

Dans les systèmes à mémoire partagée, les processeurs s'échangent les informations à travers leur mémoire centrale partagée tandis qu'ils s'échangent les informations à travers le réseau d'interconnexion dans le système d'échange de messages.

Un système à mémoire partagée typique accomplit la coordination interprocesseur par une mémoire globale partagée par tous les processeurs. Ils représentent généralement les systèmes serveurs qui communiquent par un bus et le contrôleur de la mémoire cache. Les architectures à mémoire partagée multiprocesseurs SMP (symmetric multiprocessor) sont des architectures très courantes et très populaires. Parce que l'accès à la mémoire partagée est stable, ces systèmes sont nommés SMP (symmetric multiprocessor). Chaque processeur a la même opportunité de lire/écrire dans la mémoire, avec la même vitesse. Comme exemple de machines à mémoire partagée on a : les serveurs multiprocesseurs Sun Microsystems, les serveurs multiprocesseurs Silicon Graphics Inc.

Le système par passage de messages (ou a mémoire distribuée) typiquement combine la mémoire locale et le processeur sur chaque noeud du réseau d'interconnexion. Il n y a pas de mémoire globale, ainsi il est nécessaire de déplacer les données d'une mémoire locale a une autre par le moyen d'envoi de messages. Ceci est réalisé typiquement en utilisant les commandes Send/Receive, qui doivent être écrits dans le logiciel d'application par le programmeur. Ainsi, les programmeurs doivent apprendre le paradigme du passage de messages qui implique des mouvements de données. Les exemples commerciaux de telles architectures sont nCUBE, iPSC/2 etc.

Il était aussi apparent que la mémoire distribuée est le seul moyen efficace pour augmenter le nombre de processeurs administrés par un système parallèle et distribué. Les techniques a mémoires distribuées sont les plus appropriées pour le passage a l'échelle. Un conflit a donc existé entre ces deux architectures : programmer dans le modèle de mémoire partagée était facile et concevoir des systèmes dans le modèle de passage de messages fournissait le passage a l'échelle.

Les calculateurs MIMD a mémoire commune sont appelés multiprocesseurs ou machines fortement couplées. Dans cette classe, l'accès a la mémoire est uniforme(UMA)9 ; c'est a dire tous les processeurs accèdent a toutes les zones de la mémoire commune avec la même vitesse. Le point fort de ces machines est la rapidité du partage de données entre des processeurs qui exécutent une même application parallèle. Cela est dû au fait que la mémoire commune est relativement proche des différents processeurs mis en jeu. Par exemple ENCORE, MULTIMAX, SEQUENT et BALANCE. Sur ce type d'architecture, tout le trafic entre les processeurs et la mémoire commune passe par un bus. Le trafic augmentant avec le nombre de processeurs, ce bus devient rapidement un goulot d'étranglement. C'est vraisemblablement pourquoi ce type de calculateur n'est pas massivement "scalable". Souvent, pour résoudre partiellement ce problème, une mémoire cache est associée a chaque processeur. L'objectif est de diminuer le trafic sur le bus et de rendre les données accessibles plus rapidement au processeur puisqu'il est plus rapide pour lui de les lire dans un cache rapide que dans une grande mémoire globale. Typiquement, le nombre de processeurs ne dépasse pas quelques dizaines.

Les calculateurs MIMD avec un réseau d'interconnexion sont appelés multiordinateurs ou machines faiblement couplées. Par exemple INTEL iPSC, NCUBE/7, IBM SP1 et SP2 et réseaux de Transputers. Dans cette classe de calculateurs, les processeurs sont souvent appelés "noeuds" et ne partagent rien d'autre que le réseau. L'accès a la mémoire est non uniforme(NUMA)10 ;c'est a dire tous les processeurs n'accèdent pas a toutes les zones de la mémoire commune avec la même vitesse. Ce réseau peut avoir des performances très différentes : réseau local a crossbar ou switch Omega. Ce réseau est comparativement peu utilisé par rapport au trafic sur le bus d'une mémoire commune. Il sert uniquement a échanger des données entre les processeurs en utilisant un protocole de communication de type "passage de messages". Ce type d'architecture est fortement "scalable" et le nombre de noeuds peut atteindre plusieurs centaines. Les types de plates-formes multi-ordinateurs couramment cités dans la littérature sont :

1. Les grappes homogènes : Elles sont constituées de noeuds identiques reliés entre eux a travers un réseau homogène. Beaucoup de travaux ont été réalisés dans le cadre de l'ordonnancement d'applications parallèles sur les grappes homogènes de stations de travail [25-27]. L'avantage de ces plates-formes est qu'elles permettent d'exploiter au mieux l'exécution des tâches parallèles qui nécessitent une synchronisation entre les noeuds impliqués. L'un des inconvénients des grappes homogènes est qu'il est difficile de les étendre car les offres de matériels informatiques sont en constante évolution. De plus, ces grappes sont en général constituées d'un nombre relativement limité de noeuds.

2. Les grappes hétérogènes : Elles sont également constituées de noeuds reliés au sein d'un

9uniform memory access 10Non uniform memory access

réseau local. Mais les différents noeuds et liens peuvent avoir des caractéristiques différentes. L'avantage qu'il y a à utiliser les grappes hétérogènes est de pouvoir disposer facilement de plusieurs ressources au sein d'un réseau local. Par contre, il est très difficile d'approcher les performances optimales pour les tâches parallèles du fait de la nécessité de synchronisation entre divers processus d'une même tâche.

3. Les grappes hétérogènes de grappes homogènes : Ces plates-formes qu'on qualifie souvent de »grilles légères» sont composées de plusieurs grappes distantes reliées entre elles par un réseau hétérogène. Il s'agit en général d'un réseau relativement rapide. Chaque grappe est homogène mais les caractéristiques entre deux grappes peuvent être différentes (comme exemple Grid'5000). L'avantage des grappes hétérogènes de grappes homogènes est qu'elles servent à agréger un nombre important de ressources tout en conservant un minimum d'homogénéité. On peut donc facilement adapter des travaux d'ordonnancement sur grappes homogènes à ces plates-formes extensibles qui sont de plus en plus répandues [4]. Toutefois, on ne doit pas négliger la latence entre les différents sites d'une telle plate-forme si on y déploie une application parallèle.

4. La grille: Il s'agit d'une notion de plates-formes beaucoup plus hétérogènes et plus générales. La grille est constituée [13] par l'agrégation d'unités centrales, de réseaux et de ressources de stockage distincts. Elle permet entre autre de disposer de nombreuses ressources via Internet. Aujourd'hui, quelques difficultés pratiques font qu'il n'existe quasiment pas de travaux dédiés à l'ordonnancement sur la grille. Il s'agit notamment du coût trop important des communications entre réseaux distants ou encore des problèmes de la gestion et de la disponibilité des ressources.

2.4.1 Exemple d'application des quatre classes principales

A, B, C et D sont les données. + et * sont les instructions ou les opérations.

Une des tendances claires dans le calcul est la substitution des machines parallèles coûteuses et spécialisées par les grappes de postes de travail plus rentables.

3 Grappes d'ordinateurs

3.1 Origine et évolution de grappes

Cette section donne un tour d'horizon sur les origines et l'évolution des grappes de machines. Nous avons décomposé en quatre phases l'évolution des architectures parallèles qui n'est bien entendu pas achevée, mais il nous semble que les phases décrites ci-dessous reflètent correctement la situation.

3.1.1 Les supercalculateurs

Les premières plate-formes possédant une architecture parallèle sont les machines désignées fréquemment par le terme de supercalculateurs. Il s'agit là d'un matériel très conséquent, aussi bien au niveau de la taille que des moyens nécessaires à leur exploitation. En effet, l'implantation et l'entretien d'une machine de ce type posent des problèmes logistiques concrets qui induisent un coût non négligeable en plus de la machine proprement dite, dispendieuse.

Ces machines ont un succès cyclique et il est si courant de lire dans la presse les difficultés rencontrées par tel ou tel constructeur, que l'on peut se poser la question du maintien d'une niche de ce type tant le marché paraît moribond. Cependant, les sorties de plusieurs modèles de supercalculateurs semblent indiquer un regain d'intérêt pour ces architectures citons par exemple les Cray X-1 et RedStorm, l'Earth Simulator ou encore l'IBM BlueGene/L. Ce dernier est même premier du dernier classement du top 50011 montrant bien l'enracinement des supercalculateurs (au moins de type vectoriel) dans le paysage du calcul haute-performance.

Du point de vue de l'utilisation, ces machines sont en général conçues pour des besoins applicatifs spécifiques et surtout gourmands en puissance de calcul. L'approche est de type High Performance Computing (HPC) on cherche à obtenir une importante puissance de calcul sur une durée de temps limitée. Ces architectures ne sont pas aisément extensibles et lorsque les performances deviennent insuffisantes, le changement de matériel s'impose.

3.1.2 les réseaux de station de travail

Le coût et la logistique nécessaires pour l'implantation d'un supercalculateur étant prohibitifs pour une majorité de laboratoires et d'universités, des solutions de repli (ou de rechange) ont été adoptées afin de disposer d'un accès à une machine parallèle. Or, les laboratoires possèdent des moyens de calcul souvent inutilisés qui sont les stations de travail. L'idée de base est la suivante les temps de cycles inutilisés sont exploités en fédérant un ensemble de stations avec un réseau d'interconnexion (Figure I.7). Ce matériel étant plus standard, il est moins onéreux qu'un supercalculateur et surtout plus facilement implantable.

L'approche est quelque peu différente du cas précédent, car il s'agit d'une vision de type High-Throughput Computing (HTC) où la puissance de calcul désirée doit être maintenue sur une longue période de temps (plusieurs mois, voire années). Nous avons moins affaire au parallélisme qu'aux systèmes répartis, et le projet Condor ( [8]) est typique de cette approche. C'est à partir de l'exploitation des configurations de cette nature que se sont posés les enjeux du support de la gestion dynamique des processus et des applications ainsi que de la tolérance aux pannes. Ces aspects étaient le plus souvent ignorés dans la programmation des supercalculateurs, entités fiables et offrant un modèle d'exécution statique.

11Novembre 2004

Figure I.7 - Un réseau de stations de travail

3.1.3 Les grappes de PC

Les réseaux de stations de travail ont été massivement adoptés par les laboratoires, mais les réseaux d'interconnexion étaient souvent peu rapides et constituaient un goulot d'étranglement pour les performances. L'arrivée des réseaux rapides, avec une amélioration substantielle du débit (plusieurs ordres de grandeur) a bousculé cette situation et permis l'émergence d'un nouveau type d'architecture les grappes, dont le projet NOW est un représentant [32].

Architecturalement, il s'agit d'une interconnexion de PC standards (encore moins chers que les stations de travail) avec un réseau haut-débit. Cet ensemble de machines est localisé dans un même lieu physique (exemple la même pièce), à la différence des réseaux de stations qui pouvaient s'étendre sur une échelle plus grande, comme un bâtiment par exemple. La figure I.8 schématise une telle grappe de PC.

Figure I.8 - Une grappe de PC

Cette approche est un mélange des deux précédentes les grappes sont dédiées au calcul haute-performance (HPC), mais avec des composants standards. L'extensibilité est très bonne, puisqu'il suffit

de rajouter des noeuds pour augmenter la puissance de calcul. Cependant, la difficulté d'exploitation et de programmation est plus importante qu'avec les supercalculateurs car ces derniers sont équipés d'outils spécifiques. Dans le cas des grappes, les outils d'exploitation sont souvent calqués sur ceux des supercalculateurs et la gestion dynamique des processus ou la tolérance aux pannes sont souvent reléguées au second plan. Malgré ces quelques désagréments, l'excellent ratio performances/prix favorise les grappes qui tendent à s'imposer plus de la moitié des machines classées au top 500 sont des grappes.

3.1.4 Les architectures actuelles

Ce sont ces architectures de type <grappes> qui connaissent des évolutions multiples. Nous trouvons donc les catégories décrites dans les paragraphes suivants.

les grappes de grappes

Cette évolution est naturelle et découle des excellentes capacités d'extensibilité des grappes. Le principe consiste en une interconnexion de plusieurs grappes potentiellement séparées par une forte distance géographique. En quelque sorte, il s'agit d'une méta-grappe avec une approche plutôt de type HTC, en remplaçant les stations de travail par des unités plus importantes (les grappes). Une telle évolution doit être replacée dans le contexte du [19] Grid computing et du metacomputing, dont le but est l'exploitation de ressources réparties. Cette agrégation pose de nouveaux problèmes car les composants sont hétérogènes processeurs, systèmes d'exploitation et réseaux d'interconnexion varient potentiellement d'une grappe à l'autre. La nature du réseau d'interconnexion est importante car cela permet de créer des sous-classes de grappes de grappes. L'une de ces classes de grappes de grappes est très présente les grappes faiblement couplées où les différentes grappes sont reliées par un nombre de liens tel que l'ensemble des noeuds ne forme pas un graphe complet (mais les grappes de départ continuent à l'être cependant). Les liens peuvent être à haut-débit et potentiellement distincts de ceux utilisés à l'intérieur de ces sous-grappes (Figure I.9).

Figure I.9 - Une grappe de grappes faiblement couplées

Les grappes multiplement câblées

Une autre tendance consiste à équiper une grappe avec plusieurs réseaux haut-débit. La multiplicité des technologies disponibles favorise cette situation. La grappe sera soit totalement câblée avec les multiples réseaux, soit organisée en partitions, avec un réseau haut-débit dédié à une partition particulière (Figure 1.10). La difficulté réside alors dans la capacité du logiciel à prendre en compte ou non cette multiplicité des réseaux.

Figure I.10 - Une grappe multiplement câblée (avec des partitions)

Les grappes de grande taille

Comme les grappes sont facilement extensibles, il devient possible de construire des machines avec de nombreux noeuds. Si les premières générations de grappes étaient constituées par quelques dizaines de noeuds, les générations actuelles peuvent aller jusqu'à plusieurs centaines, voire milliers d'unités (par exemple, le projet Colombus de Fujitsu avec 16384 noeuds). Dans ce cas, le problème réside dans la capacité des logiciels à exploiter de telles configurations. Les mécanismes mis en place sont-ils aussi extensibles pour suivre l'évolution du matériel?

Les grappes de type beowulf

En 1994, Thomas Sterling et Don Becker du CESDIS (Center of Excellence in Space Data and Information Sciences) construisirent une grappe de 16 processeurs DX4 reliés par un réseau Ethernet 10BaseT. Ils appelèrent cette grappe Beowulf. Une grappe Beowulf est le type de grappe le plus simple que l'on puisse rencontrer. La seule différence majeure avec un réseau de stations de travail (NOW12) est que les noeuds sont complètement dédiés aux activités de la grappe. Le concept d'une grappe Beowulf repose sur l'utilisation de matériel issu de l'industrie du COTS (Commodity Off The Shelf) et des logiciels du domaine public. Les noeuds sont généralement des PC, ils ne sont pas forcément homogènes et sont interconnectés par un réseau classique de type Ethernet ou FastEthernet. Les logiciels sont généralement du domaine public; on retrouve donc principalement le système d'exploitation

12Network of workstations

Linux13, les compilateurs GNU et des librairies de passage de messages comme MPI (Message Passing Interface) et PVM (Parallel Virtual Machine). Ce type d'architecture permet de faire tourner des applications qui ne nécessitent pas ou très peu de communications. Les applications parallèles à très gros grain14 ou à indépendance de données peuvent en bénéficier. Ce sont des architectures non génériques. Elles sont montées manuellement en utilisant des logiciels libres selon les besoins et les capacités de l'utilisateur. Ces logiciels y sont installés dépendamment de l'utilisateur et des traitements qu'il veut effectuer. Les ressources informatiques constituants ce type d'architecture peuvent être hétérogènes en termes d'unités de traitement, d'architecture, de logiciels, des réseaux d'interconnexion.

Moyens de calcul. En termes de puissance de calcul, on peut aussi bien trouver des supercalculateurs que des ordinateurs de bureau (PC), des serveurs d'exécution, des stations de travail, etc. Ce point distingue le calcul sur grille du metacomputing, qui ne fait intervenir que des supercalculateurs.

Architectures. En termes d'architecture matérielle, les ordinateurs peuvent être équipés de différents types de processeurs PowerPC, compatibles i386, des Alphas, des Mips, etc.

Logiciels. En termes d'installation logicielle, les ordinateurs peuvent avoir différents systèmes d'- exploitation avec une version précise (AIX 5.3, IRIX 6.5, Solaris 9, Linux 2.6.10, Windows XP, Ubuntu, Debian, Windows Vista etc.). Les logiciels disponibles ainsi que leurs versions peuvent également être différents et installés à des endroits variés (compilateurs, bibliothèques de calcul, etc.).

Réseaux. En termes de réseaux d'interconnexion entre les ordinateurs, les liens de communication peuvent avoir des débits, latences, gigues, taux de pertes différents.

Les avantages clés pour les grappes de type Beowulf sont la haute performance pour un prix bas, le passage à l'échelle et l'ajustement rapide aux avancées technologiques.

C'est ce genre d'architecture que nous avons adopté dans le cadre de notre travail.

3.2 Caractéristiques des grappes

Cette section présente quelques caractéristiques importantes des grappes de calcul que nous devrons prendre en considération pour l'ordonnancement des tâches de notre application parallèle le partage des ressources, l'hétérogénéité des ressources et des politiques d'administration, la sécurité et la tolérance aux fautes.

3.2.1 Accès aux ressources

Dans une grappe le partage et l'accès aux informations du système se font de manière transparente à l'utilisateur. Une information présente sur un noeud A peut être accessible sur un noeud B (Comme exemples, un utilisateur enregistré sur le noeud A peut se logger sur le noeud B sans toute fois être enregistré sur ce dernier. Egalement une donnée enregistrée sur le noeud A peut être utilisée par un utilisateur du noeud B. Toutes ces opérations se font de façon transparente aux utilisateurs de la grappe).

'3il est parfaitement adapté aux calculs parallèles, stable, efficace et libre (gratuité et code source disponible). Les mises à jour ne posent aucun problème technique ou financier.

'4Applications nécessitant de gros calculs mais peu de communications

3.2.2 Sécurité

Une grappe est constituée d'utilisateurs qui se font une confiance limitée. De plus, la mise en place d'une grappe doit respecter (et non infléchir) les politiques d'accès aux ressources de chaque ressource. Ainsi, la sécurité et ses mécanismes de mise en oeuvre sont des problématiques cruciales des grappes. La sécurité concerne l'authentification mutuelle des utilisateurs et des ressources : ces mécanismes consistent à prouver qu'un utilisateur est bien qui il prétend être, et qu'une ressource est effectivement ce qu'elle prétend être (service d'information, serveur d'exécution, etc.). La sécurité concerne également les questions d'autorisation définies au paragraphe précédent, et le chiffrement des données. Le chiffrement sert non seulement pour les informations en transit sur les liens de communication, mais aussi pour celles qui sont stockées dans les mémoires et les disques. Il évite la lecture des données secrètes et protège leur intégrité en empêchant leur modification sans autorisation. Enfin, la sécurité peut impliquer la nécessité de comptabiliser les accès (en nombre et en durée) des utilisateurs aux ressources (accounting).

3.2.3 Tolérances aux fautes

Les défaillances matérielles et logicielles font partie intégrante des grappes : lien réseau coupé, ordinateur qui tombe en panne, programme non conforme aux spécifications, etc. Pour pallier à cela, les méthodes comme le checkpointing, la migration des processus sont implémentées.

Les politiques d'accès aux ressources.

Chaque grappe décide de façon autonome et indépendante des politiques :

- d'authentification, en sélectionnant une ou plusieurs méthodes de connexion (NIS, telnet, SSH, etc.) et éventuellement des algorithmes de chiffrement des communications;

- d'autorisation d'accès aux ressources, afin de déterminer quels utilisateurs possèdent quels droits (lecture, écriture, effacement) sur chaque ensemble de données;

- d'attribution des noms d'utilisateurs.

3.3 Infrastructures matérielles des grappes

Dans la section précédente, nous avons défini les grappes de façon générale, et relativement abstraite. Cette section présente quelques infrastructures matérielles typiques des grappes.

3.3.1 Architectures matérielles des grappes

De quoi une grappe est-elle constituée? Une grappe se compose d'un ensemble de noeuds reliés par des liens réseau comme l'illustrent les deux paragraphes suivants.

Noeud de calcul et stockage

Les noeuds d'une grille de calcul sont ses moyens de stockage de données informatiques, ses moyens de calcul, des dispositifs de visualisation (écrans de réalité virtuelle immersive). Les noeuds peuvent aussi désigner des instruments de mesure ou des capteurs, tels que des télescopes, des senseurs météorologiques, mais on rencontre plus rarement ce type de ressource dans les grappes de calcul génériques qui sont déployées de nos jours. Parmi les moyens de calcul, on trouve le plus souvent des ordinateurs de bureau (PCs), des stations de travail, des serveurs d'exécution, des supercalculateurs (calculateurs parallèles à mémoire partagée tels que des SGI Origin 3000 [1] ou des SMP, calculateurs

vectoriels tels que des Cray XT3 [31]), ainsi que dans une moindre mesure, des PDA et des ordinateurs portables.

Réseau de communication

Les noeuds d'une grappe de calcul, quelle que soit leur nature, doivent être interconnectés par un réseau de communication pour coopérer en échangeant des données. Les liens réseau font partie à part entière des ressources informatiques d'une grappe de calcul.

Les noeuds peuvent être reliés par des réseaux locaux (Local Area Network, LAN), de type FastEthernet (débit 100 Mb/s, latence de l'ordre de 90 s) ou Gigabit Ethernet (débit 1 Gb/s), ou bien encore par des réseaux sans fil (débit 54 Mb/s par exemple). Les noeuds d'un cluster peuvent être interconnectés par un réseau haute performance (System Area Network, SAN) tel que Myrinet [20, 21] (débit 2 Gb/s, latence de l'ordre de la microseconde), Quadrics [24](débit plus de 6 Gb/s, latence de l'ordre de la microseconde), ou InfiniBand [16].

3.4 Infrastructures logicielles des grappes

Comme nous venons de le voir dans la section précédente, les ressources d'une grappe sont hétérogènes (du point de vue du matériel, comme des politiques d'administration), très nombreuses, et elles nécessitent des garanties en matière de sécurité. Les grappes sont donc des environnements particulièrement complexes.

L'intergiciel. Une des clés du succès des grappes est la suite logicielle qui facilite l'accès à leurs diverses ressources de manière sécurisée. Cette section définit les rôles d'une telle suite logicielle. Pour approcher l'objectif de transparence d'utilisation des grappes, on ne peut pas laisser un utilisateur qui voudrait lancer son application seul face aux ressources matérielles brutes de la grappe. Entre

- l'application qui fait un calcul utile ,

- et les multiples systèmes d'exploitation et politiques d'accès des ressources des grappes, se trouve un < intergiciel d'accès aux ressources de la grappe >.

Le rôle de cet intergiciel est de faciliter l'utilisation de la grappe, en donnant une vision plus uniforme et intégrée de ses ressources hétérogènes, et en assurant la sécurité des données et des communications.

Les langages de programmation. Les langages de programmation nécessaire pour les traitements à faire devront être installés. Typiquement, on peut avoir des langages mathématiques pour le calcul scientifique etc..

Les serveurs. Les grappes sont dotées des services d'information sur les utilisateurs du système et de sécurité. Les serveurs de partage de fichiers est également présent pour distribuer des fichiers de manière transparente à l'utilisateur.

Les grappes de PCs constituent une architecture en plein essor et qu'il faut considérer par conséquent. Elles sont dotées de caractéristiques qui rend son fonctionnement et son utilisation simple vis à vis de l'utilisateur. Pourtant le comportement hétérogène les rend très difficile à manipuler lorsqu'on y fait de la programmation parallèle tant sur le plan du choix du bon placement que de l'analyse de leur performances. Certains postulats révèlent que les performances d'une architecture parallèle sont indépendantes du nombre de processeurs existants tandis que d'autres révèlent le contraire.

4 Analyse des performances d'une architecture multiprocesseurs

Dans les sections précédentes , nous avons introduit les concepts fondamentaux liés aux systèmes multiprocesseurs. Dans cette section, nous allons aborder les notions sur l'analyse des mesures des performances des architectures parallèles. Nous allons commencer par introduire le concept des modèles de calcul liés aux multiprocesseurs. Deux modèles seront étudiés : Le modèle de calcul parallèle avec des parties séquentielles et le modèle de processus à durée égale. En étudiant ces modèles, on discutera de deux mesures qui sont : l'accélération et l'efficacité. Par la suite, des lois seront présentées pour mesurer les performances d'une architecture multiprocesseur.

4.1 Modèles de Calcul

On supposera qu'une application est divisée en tâches concurrentes15 pour l'exécution sur les différents processeurs. Partant de là, deux modèles de calcul seront décrits.

4.1.1 Modèle à durée égale

Dans ce modèle [14], on suppose qu'une application peut être divisée en n tâches égales, chacune pouvant être exécutée par un processeur. Si ts est le temps d'exécution de l'application en utilisant un seul processeur, alors le temps pris par chaque processeur pour exécuter sa tâche est tm = ts n .

comme dans ce modèle, tous les processeurs exécutent leurs tâches simultanément, alors le temps pris pour exécuter l'application est tm = ts n .

Le facteur accélération du système parallèle peut être défini comme le rapport entre le temps pris par un seul processeur pour résoudre le problème et le temps pris par le système constitué de n processeurs pour résoudre le même problème.

ts ts

S(n) = facteur d'accélération = = = n

ts

tm n

L'équation indique que, selon le modèle à durée égale, le facteur accélération résultant de l'utilisation de n processeurs est égal au nombre de processeurs utilisé, n. Un facteur important a été omis dans les relations ci-haut. Ce facteur est le surcoût des communications qui résulte du temps nécessaire aux processeurs pour communiquer et échanger les données en exécutant leurs tâches respectives. Considérons que le temps induit par le surcoût des communications est tc, alors le temps pris par chaque processeur pour exécuter sa tâche est donné par tm = ts n + tc.

S(n) =

ts ts n

= =

tm ts n + tc 1 + ntc

ts

L'équation ci-dessus indique que les valeurs relatives de ts et tc affectent l'accélération. Si on essaie d'étudier certains cas : (1) si tc << ts alors le facteur accélération est approximativement égal à n; (2) si tc >> ts alors le potentiel accélération est ts

tc << 1; (3)sitc = ts alors le potentiel accélération est n

n+1

1, pour n >> 1.

Dans l'optique de faire varier le facteur accélération entre 0 et 1, on le divise par le nombre de processeurs, n. La mesure résultante est appelée efficacité, . L'efficacité est une mesure de l'accélération par processeur. Selon ce modèle, l'efficacité est égale à 1 si le surcoût dû aux communications est

15tâches qui se communiquent les données

ignoré. Cependant si le surcoût dû aux communications est pris en compte, l'expression de l'efficacité est la suivante : î= 1

1+ tc

ts

Bien que simple, le modèle de durée égale n'est pas réaliste. Cela parcequ'il est basé sur le fait qu'une application peut être divisée en tâches égales qui peuvent être exécutées par des processeurs. Cependant, il est important ici d'indiquer que les algorithmes réels contiennent des parties séquentielles qui ne peuvent pas être divisées entre les processeurs. Ces parties séquentielles doivent être exécutées sur un seul processeur.

Considérons, par exemple, les segments de programme donnés dans la figure I.11. Dans ces segments de programme, on suppose qu'on commence avec une valeur de l'un des deux vecteurs a et b stockés dans un des n processeurs disponibles. Le premier bloc de programme (encadré dans un carré) peut être résolu en parallèle; C'est à dire que chaque processeur peut calculer un élément du tableau c. Les éléments du tableau c sont distribués entre les processeurs et chaque processeur a un élément. Le prochain segment de programme ne peut pas être exécuté en parallèle. Ce bloc aura besoin que les éléments du tableau c soient envoyés à un processeur et additionnés sur ce processeur.

Le dernier segment de programme peut être résolu en parallèle. Chaque processeur peut mettre à jour ses éléments de a et b. Cet exemple illustratif montre qu'un modèle de calcul réaliste devrait

Figure I.11 - Segments de programme

assumer l'existence de parties séquentielles dans un programme qui ne peuvent être divisées. Cela est la base du modèle suivant.

4.1.2 Modèle de calcul parallèle avec des parties séquentielles

Dans ce modèle de calcul[14], une fraction f d'un programme donné est séquentielle. La partie restante (1-f ) elle est parallélisable.

Les dérivations similaires effectuées dans le modèle à durée égale vont résulter comme suit.

Le temps nécessaire pour exécuter le programme sur n processeurs est

tm = fts + (1 - f)(ts n )

.

Le facteur accélération est par conséquent donné par:

S(n) =

ts n

fts + (1 -- f)(ts n ) = 1 + (n - 1)f

Selon cette équation, l'accélération due à l'accélération des n processeurs est déterminée primairement par la fraction de code non parallélisable. Si le programme est complètement séquentiel, c'est à dire, f =1, alors aucune accélération ne sera atteinte peu importe le nombre de processeurs utilisés. Ce principe est la loi d'Amdahl.C'est intéressant de noter que selon cette loi le facteur accélération maximal est donné par:

lim

n-400

1

S(n) = f

Par conséquent, selon la loi d'Amdahl l'amélioration de la performance(vitesse) de l'algorithme parallèle par rapport à l'algorithme séquentielle n'est pas limitée par le nombre de processeurs mais plutôt par la partie de l'algorithme qui ne peut pas être paralléliser. A première vue, la loi d'Amdahl indiques que peu importe le nombre de processeurs utilisé, il existe une limite intrinsèque sur l'utilité des architectures parallèles utilisées. Souvent et selon la loi d'Amdahl, les chercheurs étaient amenés à penser qu'une substantielle croissante du facteur d'accélération ne serait pas possible en utilisant les architectures parallèles. On discutera de la validité de cela et d'un postulat similaire dans la section suivante. Cependant, montrons l'effet du surcoût dû aux communications sur le facteur d'accélération sachant qu'une fraction f du programme n'est pas parallélisable. Comme on l'a mentionné depuis le début, le surcoût dû aux communications devrait être inclus dans le temps de traitement.

Considérons le temps induit par le surcoût des communications, l'accélération est donnée par:

S(n) =

ts n

=

fts + (1 -- f)(ts n ) + tc 1 + (n - 1)f + ntc

ts

Le facteur d'accélération maximum dans ces conditions est donné par:

lim

n-400

S(n) = lim

n-400

n =

1 + (n - 1)f + ntc

ts

1

f + tc

ts

La formule ci-dessous indique que le facteur d'accélération n'est pas déterminé par le nombre de processeurs parallèles utilisés mais par la fraction du programme qui n'est pas parallélisable et par le surcoût des communications.

Ayant considéré le facteur d'accélération, calculons maintenant la mesure d'efficacité. On sait que l'efficacité est le ratio entre le facteur d'accélération et le nombre de processeurs n. L'efficacité peut être calculée ainsi :

î(sans surcoût de communications) = 1

1+(n-1)f

1

î(avec surcoût de communications) =

1+(n-1)f+n tc

ts

Comme dernière observation, il est a noté que dans une architecture parallèle, les processeurs maintiennent un certain niveau d'efficacité. Cependant, comme le nombre de processeurs augmente, il devient difficile de les utiliser efficacement. En vue de maintenir un certain niveau d'efficacité de processeur, il devrait exister une relation entre la fraction séquentielle du programme, f, et le nombre de processeurs employés. Après avoir introduit les deux modèles de calcul ci-haut, nous présenterons des lois de performance qui ont des hypothèses sur le gain potentiel des architectures parallèles. Parmi ces lois on a celle d'Amdahl, de Gustafson-Brasis.

4.2 Un argument pour les architectures parallèles

Dans cette section, on introduit un nombre de lois nécessaires pour exprimer l'utilité des architectures parallèles.

4.2.1 Loi d'Amdahl

Nous avons défini précédemment l'accélération d'un système parallèle comme le ratio entre le temps pris par un seul processeur pour résoudre le problème divisé par le temps pris par le système parallèle constitué de n processeurs pour résoudre le même problème.

ts

S(n) = fts + (1 - f)(ts n )

lim

n-400

1

S(n) = f

Une observation intéressante à faire ici est que selon la loi d'Amdahl[3], f est fixé et n'augmente pas avec la taille du problème, n. Cependant, il a été pratiquement observé que certains algorithmes parallèles réels ont une fraction f qui est une fonction de n.

Supposons que f est une fonction de n telle que lim f(n)=0. Alors

S(n) = lim

n-400

n

1 + (n - 1)f(n) ~ n

Ceci est une contradiction à la loi d'Amdahl.

Cette loi stipule donc qu'une application parallèle peut se décomposer en une partie parallélisable et une partie non parallélisable. Le temps d'exécution de la partie parallélisable est inversement proportionnel aux nombre de processeurs tandis que le temps d'exécution de la partie non parallélisable ne varie pas quelque soit le nombre de processeurs disponibles (elle ne s'exécute que sur un processeur). On peut remarquer que ce modèle ne tient pas explicitement compte d'éventuels coûts de communications entre les processeurs. Ce modèle est donc plutôt adapté aux tâches pour lesquelles les communications internes sont négligeables ou celles dont les calculs recouvrent totalement les communications.

Ce modèle est illustré à la figure I-12. On voit effectivement qu'avec plusieurs noeuds pour le calcul, le temps parallèle peut tendre vers zéro mais le temps séquentiel ne change pas.

Figure I.12 - Modèle Amdahl

4.2.2 Loi de gustafson

En 1988, Gustafson and Barsis dans les laboratoires Sandia ont étudié le paradoxe crée par la loi d'Amdahl et le fait que les architectures parallèles constituées de centaines de processeurs étaient construites avec amélioration de performances. En introduisant leur loi, Gustafson a reconnu que la fraction non parallélisable d'un algorithme peut ne pas être connue à priori. Ils affirment qu'en pratique, la taille du problème augmente avec le nombre de processeurs, n. Ceci contredit la base de la loi d'Amdahl qui stipule que le temps d'exécution de la partie parallélisable d'un programme, (1-f ), est indépendant du nombre de processeurs, n. Gustafson et Brasis ont postulé que lorsqu'on utilise un processeur plus puissant, le problème tend à utiliser plus de ressources. Ils ont trouvé que la partie parallèle du programme croît avec la taille du problème. Ils ont postulé que si s et p représentent respectivement le temps d'exécution de la partie séquentielle et de la partie parallèle, alors s + p * n représente le temps requis par un processeur séquentiel pour exécuter le programme. Ils ont ainsi introduit un nouvel facteur, appelé scaled sppedup factor, SS(n), qui peut être calculé ainsi :

s + pn

SS(n) = = s + p * n = s + (1 - s) * n = n + (1 -- n) * s

s + p

Cette équation montre qu'on peut atteindre une performance parallèle efficace contrairement à l'accélération d'Amdahl. L'accélération devrait être mesurée en augmentant le nombre de processeurs pas en fixant la taille du problème L'accélération et l'efficacité sont deux facteurs pour mesurer les performances sur une architecture parallèle. Mais ils ne tiennent pas compte de l'architecture du réseau d'interconnexion pourtant un facteur important à prendre en compte pour pouvoir effectuer un bon ordonnancement des tâches composantes d'une application parallèle.

Conclusion

Dans ce chapitre, après avoir donné les motivations et les objectifs du calcul parallèle, nous avons présenté un certain nombre de concepts importants pour le calcul haute performance (HPC) via le parallélisme. En particulier, on a fourni des concepts généraux et terminologies utilisés dans le contexte des multiprocesseurs. La populaire classification de Flynn a été fournie. Nous avons donné les caractéristiques explicites des architectures SISD, MISD, SPMD, SIMD et MIMD. Cette classification est aujourd'hui obselète. La plupart des machines parallèles sont MIMD à savoir l'architecture à mémoire partagée qui regroupe les calculateurs multiprocesseurs qui ne permet pas le passage à l'échelle contrairement à l'architecture à mémoire distribuée qui regroupe les calculateurs multiordinateurs. Nous avons présenté un cas particulier des multiordinateurs à savoir l'architecture des grappes de calcul, plus particulièrement celles hétérogènes. Ces dernières constituera notre architecture cible dans le cadre de notre travail. On a vu que deux grands modèles de programmation sont utilisés sur les architectures distribuées de type grappe de machines le passage de messages et la mémoire partagée. Dans notre travail on utilisera le premier modèle et plus précisément le standard MPI qui est doté de caractéristiques favorables à notre machine cible. Nous avons étudier comment analyser les performances d'une application parallèle avec des postulats de Flynn et Gustafson en utilisant les paramètres d'accélération et d'efficacité. Une fois qu'on connaît parfaitement les spécificités de notre architecture cible tant matérielle que logicielle, il nous revient de bien représenter notre application parallèle pour pouvoir l'exécuter sur les ressources de calcul. Dans le chapitre suivant nous verrons comment représenter une application parallèle de manière plus formelle en graphe et quels sont les différents modèles qu'on peut utiliser pour ordonnancer les tâches.

Chapitre II

CONCEPTS D'ORDONNANCEMENT

A

Près que notre application soit conçue et réalisée en ensemble de tâches, une assignation de ces tâches aux processeurs de notre architecture doit être déterminée. Ce problème est appelé problème d'ordonnancement et est connu comme étant le plus grand défi dans le domaine du calcul distribué

et parallèle. Le but de l'ordonnancement est de déterminer une bonne allocation des tâches aux processeurs de l'architecture. Un algorithme d'ordonnancement prend en compte une représentation de l'application sous forme de graphe de précédence, de flots de données ou de tâches et consiste à répartir ces tâches sur les différents processeurs du système en fonction d'un critère de performance donné. Certains modèles d'ordonnancement ont des supports de communication entre les processeurs de la machine cible tandis que d'autres négligent l'influence des communications entre les processeurs de la machine cible. Nous les présenterons et illustrerons après avoir décrit les différentes représentations d'une application en tâches par un graphe.

1 Modélisation d'une application

L'algorithme est faite principalement de deux façons, chacune utilisant un graphe orienté comme structure de base. Nous pouvons représenter un programme par un graphe de flots de données (data-flow graph), par un graphe de précédence(precedence task graph) [5]. En dehors de ces deux types, nous avons un autre type plus général : le graphe de tâches(task graph). Dans la suite, nous caractérisons ces représentations sous la forme d'un graphe orienté sans cycle (C, V ) où G est l'ensemble des sommets et V est l'ensemble des arcs. Un graphe de tâches est composé des noeuds représentant les tâches et les arcs représentant les dépendances entre les tâches. Nous utilisons le programme ci-dessous (figure II-1) pour donner un exemple de ces types de graphe.

1.1 Graphe de précédence

Dans la représentation d'un programme par un graphe de précédence, l'algorithme est divisé en unités de base dénommées tâches (qui sont des instructions ou groupes d'instructions). Les tâches sont représentées par des sommets du graphe. Les dépendances entre les tâches sont explicitées par des arcs. L'existence d'un arc (u, v) d'une tâche u à une tâche v dans le graphe signifie que la tâche v ne peut pas être exécutée sans les données produites par la tâche u. Nous associons à chaque arc un poids proportionnel à la quantité de données à transmettre, et à chaque sommet un poids correspondant au

Figure II.1 - Exemple de Programme

temps de calcul de la tâche. Dorénavant, nous ferons référence à cas valeurs comme poids de l'arc ou du sommet. Lorsque les arcs ne sont pas associés à des poids, c'est à dire seules les dépendances entre les tâches sont données, nous avons la représentation par graphe de dépendance.

Un graphe de précédence est donné en exemple dans la figure II.2 où les tâches sont représentées par des cercles et les relations de précédence par des arcs. Les dépendances étant introduites pour régler des conflits d'accès à des données, elles peuvent être interprétées comme des communications entre les tâches. Dans ce type de graphe, une tâche est considérée comme prête dès que toutes les tâches qui la précèdent dans le graphe sont terminées.

1.2 Graphe de flots de données

Si les dépendances entre tâches sont considérées comme des communications d'échange de données, le graphe de flots de données est construit à partir de l'évolution des données. Les relations de précédence sont induites par la circulation des données. Typiquement, les sommets correspondent à l'évaluation d'une instruction et les précédences aux accès en lecture ou écriture des opérandes [10]. Un graphe de flots de données est un graphe biparti, où sont représentées les tâches et les données. La figure II.3 représente le graphe de flots de données pour une exécution du programme du calcul de fibonacci. Connaissant une représentation d'un programme par un graphe de flots de données, sa transformation en graphe de précédence est immédiate car le premier fournit plus d'informations que le dernier. La différence entre les graphes de précédence et de flots de données se situe au niveau des synchronisations. Dans le graphe de flot de données, une tâche est considérée comme prête dès que les données qu'elle a en entrée sont disponibles. Notons néanmoins qu'un graphe de flots de données contient les informations d'un graphe de précédence.

A priori, les tâches peuvent être quelconques et le graphe de précédence inconnu au moment de

Figure II.2 - Un graphe de précédence pour le programme. Les tâches sont représentées par des cercles et les arcs représentent les précédences.

l'exécution d'un programme. Pour un graphe de précédence G donné, nous adoptons la terminologie suivante :

Successeurs : l'ensemble des successeurs d'un sommet v est constitué de tous les noeuds u tels qu'il existe un chemin orienté de v à u dans G.

Successeurs directs : l'ensemble des successeurs directs d'un sommet v est constitué de tous les noeuds u tels qu'il existe un arc de v à u dans G.

Prédécesseurs : l'ensemble des prédécesseurs d'un sommet v est constitué de tous les noeuds u tels qu'il existe un chemin orienté de u à v dans G.

Prédécesseurs directs : l'ensemble des prédécesseurs directs d'un sommet v est constitué de tous les noeuds u tels qu'il existe un arc de u à v dans G.

Largeur : le cardinal du plus grand ensemble de sommets du graphe tel qu'il n'existe pas deux sommets appartenant au même chemin orienté.

Chemin critique: le plus long chemin orienté du graphe, prenant en compte les temps de calcul. Granularité : rapport entre le poids des sommets et des arcs. La granularité p d'un graphe orienté G est le rapport entre le plus petit poids d'un sommet et le plus grand poids d'un arc de G. Si p < 1 alors le graphe est dit à grain fin, sinon il est dit à gros grain. Intuitivement, les tâches d'un graphe à gros grain calculent plus qu'elles ne communiquent.

Pour illustrer ces terminologies, dans le graphe orienté G de la figure II.4, nous avons (v8, v9, v10, v11) pour successeurs du sommet v5. Les successeurs de v2 sont (v6 , v11). Les prédécesseurs directs de v9 sont (v5, v7). La largeur du graphe G est de 4. Si toutes les tâches du graphe G ont le même poids, le graphe a trois chemins critiques : (v1, v3, v7, v9), (v1, v4, v7, v9) et (v1, v5, v8, v10).

Figure II.3 - Un graphe de flots de données pour le programme. Les tâches sont représentées par des cercles. Les données à transférer dans un rectangle.

Figure II.4 - Graphe de précédence G

1.3 Graphe de tâches

Dans ce type de graphe (figure II-5), un sommet du graphe représente un calcul local à un processeur. Ces calculs locaux sont nommés tâches. Les arcs du graphe représentent les contraintes de précédence entre calculs. Par exemple un arc peut modéliser le fait qu'une tâche attend un résultat produit par une autre tâche.

Le graphe peut être pondéré. La pondération d'un noeud représente le coût (nombre d'instructions, temps, etc.) du calcul associé à ce noeud. La pondération d'un arc représente le volume de données à transmettre d'un noeud à un de ses successeurs.1

Une tâche est prête si tous ses prédécesseurs ont déjà été exécutés et que les données utiles, calculées par les prédécesseurs de la tâche ont été acheminées dans la mémoire locale du processeur où vont avoir lieu les calculs.

Si les données sont déjà présentes localement, elles n'ont pas besoin d'être communiquées. Le coût de transfert de données entre deux tâches exécutées par le même processeur est donc considéré comme nul.

Si les données ne sont pas présentes localement, il va falloir les communiquer. Une tâche ne devient prête que lorsque toutes les données en provenance de tous ses prédécesseurs sont finalement arrivées. La date à laquelle elle devient prête dépend donc du nombre de prédécesseurs, du volume des données à transférer et du temps que va mettre le réseau pour effectuer chacun de ces transferts.

Les différences entre les modèles d'exécution correspondent à des différences dans l'évaluation du coût de telles communications. Ces différences ont un impact sur les stratégies d'ordonnancement. Un exemple de graphe de tâches correspondant au programme du Fibonacci ci-haut est illustré ci-dessous.

Figure II.5 - Exemple de graphe de tâche du programme. Les chiffres en bleu représentent les coûts de chaque tâches. Ceux en noir représentent le volume des données à transférer d'une tâche à l'autre par unité de temps.

'Contrairement, au graphe de flots de données, les données ne seront pas représentées mais plutôt le volume des données à transmettre. Egalement, en plus des tâches représentées dans le graphe de précédence, leur coût de calcul seront représentés.

L'ordonnancement des calculs et le placement des données sont deux facteurs importants pour concevoir une application parallèle efficace; nous présentons par la suite les modèles typiques d'ordonnancement que l'on rencontre dans la littérature .

2 Les Modèles classiques d'ordonnancement

Le comportement réel d'une application est relativement facile à prévoir en séquentiel. On peut aisément approcher le temps d'exécution d'un programme, en étudiant par exemple sa complexité. En parallèle, d'infimes variations dans l'environnement d'exécution, que ce soit sur un noeud de calcul ou sur la rapidité du réseau, peuvent changer complètement le temps d'exécution d'un algorithme non déterministe sensible aux synchronisations. Quelques outils de réexécution déterministes. existent et peuvent faciliter le débogage des applications. Le comportement réel d'une application est donc très souvent difficile à prévoir, et plus encore à optimiser. Dans une exécution séquentielle, les portions de code où le programme passe le plus de temps, sont facilement identifiables. En parallèle, l'optimisation du code n'est pas suffisante, il faut aussi que l'ordre des opérations et leurs lieux d'exécution soient judicieusement choisis. Dans le cas contraire, même si chaque opération se déroule rapidement, les processeurs de la machine peuvent rester inactifs en attendant des données calculées sur d'autres processeurs. Le problème de ce choix est nommé autrement problème d'ordonnancement. Le temps d'exécution va donc dépendre de toutes les charges de calculs de tous les processeurs et de la charge du réseau. En pratique, pour pouvoir concevoir et évaluer des algorithmes, les machines parallèles sont modélisées plus ou moins finement. Les différences entre les modèles concernent principalement la modélisation des communications. Pour qu'un ordonnancement soit valide, Une tâche ne débutera son exécution que lorsque ses prédécesseurs directs ont terminé leurs exécutions et lorsque les données nécessaires pour leurs exécutions sont présentes sur les machines sur lesquelles elles s'exécuteront respectivement.

En d'autres termes, il faut qu'il respecte les contraintes de précédence et du volume des données à communiquer entre les tâches. Ces contraintes dépendent du modèle de coût des communications.

2.1 Modèles à coût de communications nul

Beaucoup de travaux ont été menés en négligeant l'influence des communications. Cette hypothèse est plus ou moins réaliste. Elle est justifiée pour les applications dont les coûts de calcul sont très grands devant les coûts de communication et pour des exécutions se déroulant sur des machines parallèles à mémoire partagée.

Ordonnancer un graphe sans tenir compte des coûts de communication est relativement facile. De très bonnes garanties de performance peuvent être obtenues avec des heuristiques simples, par exemple, en commençant à exécuter une des tâches prêtes sur le premier processeur qui devient disponible. Quel que soit l'ordre dans lequel les tâches sont placées, l'exécution dure moins de 2 fois plus longtemps que le meilleur ordonnancement. Pour être précis, la garantie est au pire de 2- m, où m est le nombre de processeurs de la machine.

En fonction du graphe de précédences, de bien meilleures approximations peuvent être trouvées. Par exemple, si toutes les tâches sont indépendantes, en plaçant la plus grosse tâche d'abord, on obtient un rapport de performance avec le meilleur ordonnancement de 4/3. L'exemple des tâches indépendantes est en fait pleinement approximable. Pour tout , un ordonnancement s'exécutant en moins de 1+ fois le temps du meilleur ordonnancement peut être construit en temps polynômial ( polynôme en n, le nombre de tâches, et ~ ). En pratique, ce modèle est réaliste dans deux cas :

- la mémoire de la machine parallèle est physiquement partagée. Il n'y a pas de communications car les données sont toujours «locales»;

- le coût de calcul de chaque tâche est très grand devant le coût d'une communication. Les com-

munications n'influencent pas réellement le temps d'exécution si l'algorithme est déterministe.

Un premier modèle plus général consiste à prendre comme modèle du temps d'acheminement des données de la mémoire d'un processeur à un autre, une fonction de la taille des données.

2.2 Modèle délai

La première extension possible est de considérer un délai d constant, lors de la transmission d'un message dans le réseau entre deux tâches situées sur des processeurs différents. Ce délai est une fonction de la taille des données à acheminer. Les processeurs peuvent calculer librement sans être «gênés» par les communications. Il n'y a pas, dans ce modèle, de contention (embouteillage) sur le réseau.

L'ordonnancement dans ce modèle est généralement plus difficile que l'ordonnancement avec coût de communication nul. La difficulté d'ordonnancer un graphe de tâches dans ce modèle dépend du rapport entre le plus petit coût de calcul d'une tâche et le plus grand coût de communications entre deux tâches.

1. Dans les problèmes dits à petit temps de communications, le coût de communication est plus petit que le coût de calcul. Ce sont des problèmes relativement simples car ils sont proches des algorithmes sans communication..

2. Dans les problèmes dits à grand temps de communication, le coût de communication est plus grand que le coût de calcul. Trouver une solution proche de la solution optimale devient plus difficile dans le cas général. Il est possible de limiter le nombre de communications en dupliquant des tâches.

Lorsqu'une application parallèle est considérée à son grain le plus fin, le coût des communications est souvent bien supérieur à celui des quelques calculs locaux. En pratique, des algorithmes de regroupement linéaire sont utilisés pour ordonnancer ces graphes. Ils consistent à diviser le graphe en chaînes critiques. Une chaîne critique est un chemin dans le graphe avec des communications de coût important. Une chaîne est exécutée par le même processeur. Le problème revient alors à distribuer ces chaînes sur les processeurs en essayant de minimiser le coût des communications entre chaînes. Ceci peut être fait par un algorithme de partitionnement de graphe non-orienté. Malheureusement, ces algorithmes ont des garanties de performance qui dépendent du coût de la plus grande chaîne de communication.

Approximations faites dans le modèle délai

En fait, le modèle délai néglige deux aspects importants de la modélisation des communications d'une application parallèle :

- le surcoût d'exécution dû à la gestion des communications : Pile de protocole à l'envoi et à la réception, interruptions, etc. A cela, on peut encore ajouter les éventuelles copies de mémoires lors des communications. Dans le modèle délai, un grand nombre de communications peut être fait sans surcoût, tant que ces dernières sont recouvertes par du calcul.

- la contention due aux goulots d'étranglements du réseau. Dans les algorithmes par phases, tous les processeurs ont tendance à envoyer et recevoir leurs messages en même temps. Suivant l'architecture et la performance du réseau, cela peut entraîner un ralentissement important dans la vitesse d'acheminement d'un message.

Ces deux aspects sont partiellement pris en compte par deux autres modèles, logP et BSP.

2.3 Les modèles LogP et BSP

Ces deux modèles sont un raffinement du modèle délai pour être plus proche du comportement matériel : LogP modélise plus finement le coût d'une communication tandis que BSP est en fait un modèle de machine et d'exécution.

LogP

Le modèle LogP est une extension du modèle délai plus proche du véritable comportement d'une machine parallèle. C'est un modèle multiprocesseurs à mémoire distribuée dans lequel les processeurs font des communications point à point. Le modèle spécifie les caractéristiques de performance du réseau d'interconnexion mais ne décrit pas la structure du réseau. Les paramètres principaux du modèle sont :

L(Latency) : le temps de transmission d'un court message d'un processeur source à l'autre.

o(Overhead) : le surcoût en temps nécessaire au processeur pour recevoir (or) et transmettre un message (os), durant lequel le processeur ne peut effectuer d'autres opérations.

g(Gap) : L'intervalle de temps minimum entre deux transmissions consécutives ou deux réceptions consécutives sur un processeur. 1/g est le débit de communication par processeur.

P(Processor) : le nombre de processeurs (les éléments processeur et mémoire ) dans le réseau.

Le modèle LogGP est une extension du modèle LogP et il ajoute un paramètre pour prendre en compte le débit pour les longs messages. Ce paramètre est :

C : Gap par octets pour les longs messages.

On suppose que le réseau a une capacité finie, telle que au plus [L/g messages peuvent être en transit d'un processeur à un autre chaque fois. Si un processeur essaie de transmettre un message qui dépassera cette limite, jusqu'à ce que le message soit envoyé en respectant la capacité limite.

La figure II.6 schématise ce modèle et la figure II.7 donne un exemple illustratif.

Figure II.6 - Le modèle LogP

BSP

Le modèle BSP (Bulk-synchronous Parallel) sert à rendre les algorithmes parallèles et leur analyse assez détaillé pour qu'on puisse en tirer des prévisions assez réalistes sur le temps de calcul. Son principe de base est de concevoir toute architecture parallèle comme réseau d'ordinateurs séquentiels complets et de la quantifier par un petit nombre de paramètres numériques. Dans le modèle BSP, une machine parallèle à mémoire distribuée est décrite en termes de trois éléments :

- Les modules processeur/mémoire,

Figure II.7 - A gauche nous avons une représentation de l'ensemble des processeurs P=8, L=6, g=4, o=2 et à droite l'activité de chaque processeur dans le temps. Le nombre montré pour chaque noeud est le temps auquel chaque processeur a reçu les données et peut commencer à envoyer.

- Le réseau d'interconnexion,

- Un synchroniseur qui effectue une barrière de synchronisation.

Un calcul est une séquence de super-étapes. Pendant une super-étape, chaque processeur effectue un calcul local, reçoit et envoie des messages et est sujet aux contraintes suivantes le calcul local ne doit dépendre que des données présentes dans la mémoire locale du processeur au début de la superétape et un processeur doit envoyer au plus h et recevoir au plus h messages dans une super-étapes. Une telle communication est appelée une h-relation.

Les modèles d'exécution servent de base à la programmation d'une machine parallèle. Il donne la sémantique d'exécution. Un des principaux buts des modèles d'exécution est de servir à la prédiction du temps d'exécution d'un programme parallèle. Nous nous intéresserons aux machines MIMD. Les processeurs sont identiques c'est à dire qu'ils ont la même vitesse de traitement. Les modèles de machines que nous avons décrit au chapitre 1 servent à classer les machines existantes mais ils ne sont pas suffisants lors du développement d'une application. Si nous voulons connaître le traitement des conflits lors de l'accès à une donnée partagée, ou les formes de communication entre les processeurs, nous avons besoin des modèles d'exécution.

3 Modèles d'exécution et ordonnancement

Il est clair que le modèle d'exécution doit être adapté au modèle de machine. Un modèle d'exécution qui ne prend pas en compte le temps d'accès à une donnée distante s'avère peu pratique pour une machine MIMD de type NUMA. Nous allons diviser la présentation des modèles selon leur origine. Nous présenterons des modèles théoriques, c'est-à-dire ceux qui n'ont pas été inspirés de machines existantes d'une part et des modèles basés sur les caractéristiques de machines réelles d'autre part.

3.1 Le modèle PRAM

Le modèle PRAM (Parallel Random Access Machine) est un modèle théorique utilisé en calcul parallèle et qui a servi de raffinement pour obtenir d'autres modèles. Il est le premier modèle à avoir été proposé pour l'informatique parallèle [? ]. Encore aujourd'hui il sert de référence. Il est très populaire pour l'évaluation et la comparaison d'algorithmes parallèles [17]. Ce modèle comprend une unité de contrôle, des processeurs identiques fonctionnent en cadence par cycle d'une instruction, et qui ont accès à une mémoire globale commune. En dehors de la mémoire globale, chaque processeur a

sa mémoire locale. Le nombre de processeurs ainsi que la taille de la mémoire sont illimités. Ce modèle se révèle irréaliste en pratique, car le coût de maintien d'une mémoire globale dépend du nombre de processeurs. Dans le but de définir les règles d'accès à la mémoire dans le modèle PRAM, plusieurs versions ont été proposées. Les types sont :

- le EREW (Exclusive Read Exclusive Write), où chaque cellule est accédée par au plus un processeur à chaque cycle,

- le CREW (Concurrent Read Exclusive Write),

- le CRCW (Concurrent Read Concurrent Write), où l'accès aux cellules peut se faire par plusieurs processeurs pour la lecture, et pour la lecture et écriture, respectivement.

Dans le dernier cas, des règles de résolution de conflits sont définies. Les plus courantes, en ordre croissant de complexité sont : arbitraire, prioritaire et combinaison de valeurs (par un maximum, une somme, etc). Dans les modèles du type PRAM les problèmes de communication sont masqués. La communication est incluse implicitement dans le modèle. Pourtant en pratique c'est un point important dont il faut tenir en compte. La figure II.8 illustre les composants du modèle PRAM.

Figure II.8 - Le modèle PRAM pour le calcul parallèle

3.2 Les modèles avec délai de communications

Dans les modèles avec délai de communication, il existe un support pour la communication entre les processeurs. Ce support consiste en l'envoi et la réception de messages. Dorénavant nous dénotons par modèles délai, les modèles que considèrent uniquement la taille des tâches et le délai de communication entre tâches successives allouées à des processeurs différents, lequel peut être aussi considéré comme étant zéro.

Les modèles délai et des techniques d'ordonnancement associés ont été proposés simultanément. Pour ne pas anticiper la présentation de l'ordonnancement, nous allons donner une description informelle. Un ordonnancement d'un graphe sur une machine consiste à attribuer à chaque tâche du graphe un processeur et une date de début d'exécution.

Lors de la transmission ou de la réception d'un message dans une machine réelle, le processeur est occupé pendant une période de temps (avec des copies mémoire, allocation de tampons, etc.). Les modèles de cette section ne prennent pas en compte cette période sur le temps d'exécution des processeurs. Le recouvrement total des communications par du calcul est autorisé, c'est-à-dire que les processeurs peuvent calculer pendant les communications. Les modèles délai ne prennent également pas en compte la congestion du réseau. Le surcoût de communication sur le temps de calcul et la congestion ont été considéré dans le modèle LogP. Nous présentons d'abord le modèle avec bande passante illimitée, c'est-à-dire, sans surcoût de communication. Ensuite nous présentons les modèles avec bande passante limitée, ce qui introduit des délais de communication. Une des façons d'alléger ce surcoût peut se faire à travers la duplication de tâches. Dans ce cas, nous pouvons au lieu de communiquer à partir des prédécesseurs, dupliquer quelques-uns d'entre eux. Les paramètres que nous utiliserons pour les modèles suivants sont le nombre de processeurs et la possibilité de dupliquer des tâches.

Nous présentons des exemples d'exécution du graphe G de la figure II.4 sous les différents modèles d'exécution. La représentation utilisée est le diagramme de Gantt (diagramme espace temps classique où l'espace correspond à l'occupation des processeurs) où les tâches, les communications et les temps d'attente sont placés selon leurs dates, processeurs et durées d'exécution. Le poids des sommets du graphe G sont identiques, le poids de ses arcs sera explicité pour chaque modèle.

3.2.1 Modèle UET Le modèle

L'approche théorique de base est simplement d'ignorer le temps de communication entre processeurs. La bande passante est considérée illimitée. Le modèle UET (unit execution time) a été proposé par Papadimitriou et Ullman [22]. Le temps d'exécution des tâches est unitaire, les attentes dues aux communications ne sont pas considérées. Il est clair que dans ce cas la duplication de tâches s'avère inutile. Ce modèle est similaire au modèle PRAM.

Ordonnancement avec UET

Dans le diagramme de la figure II.9, nous présentons un schéma d'exécution optimal. Les zones rayées correspondent au temps d'inactivité, cette notion sera utilisée dorénavant. L'ordonnancement est valide si la contrainte de précédence est vérifiée. Au temps t = 0, on place les tâches sans prédécesseurs directs v1 et v2 sur des processeurs libres p1 et p2. A ce moment, un processeur sera inactif. Au temps t = 1, étant donné qu'il n y a que 3 processeurs disponibles , on va donc choisir et placer les tâches v3, v5, v4 sur les processeurs. L'ordre importe peu car ils ont le même temps d'exécution et le temps de communication est nul. Au temps t = 2, on choisit v6 qui n'était pas encore allouée et aussi les tâches v5 et v7 sur les 3 processeurs. Au temps t = 3, on place les trois dernières tâches v11, v9, v10. On remarque bel et bien que cet ordonnancement est valide et optimal car le temps d'exécution est de 4 qui est presque égal au nombre de tâches divisé par le nombre de processeurs = 11/3.

Figure II.9 - Exécution dans le modèle UET

3.2.2 Modèle UET-UCT

Le modèle

L'extension naturelle du modèle UET considère de manière simplifiée les communications. Lorsque les temps d'exécution des tâches ainsi que les temps de communication sont unitaires, nous avons le modèle UET-UCT (unit execution time - unit communication time). Ce modèle a été proposé par Rayward-Smith [28]. Les schémas d'exécution avec et sans duplication sont représentés dans la Figure II.10.

Dans l'exemple de la figure II.10, en permettant la duplication, le temps d'exécution a été diminué d'une unité. Dans la figure II.10 et dorénavant, lorsqu'une tâche est exécutée plusieurs fois, une de ses allocations est dénommée par l'index de la tâche. Les autres exécutions d'une tâche v sont désignées par v0 .

Ordonnancement avec UET-UCT

Ici l'idée est de chercher à placer les tâches qui communiquent sur le même processeur pour annuler le temps de communication.

Sans duplication : Au temps t = 1, on place les tâches sans prédécesseurs v1 et v2 sur p1 et p2 respectivement. p3 est à ce moment inutilisé. Au temps t = 2, on place les tâches v5 et v6 sur p1 et p2 respectivement car v5 communique avec v1 et v6 avec v2. p3 est toujours inutilisé. Au temps t = 3, on place v4 sur p3 ( v1 a terminé son exécution plus le temps de communication entre p1 et p3.) Avec le même principe, on parcourt toutes les tâches avec un temps de 6. On remarque que p3 passe beaucoup de temps inactif.

Avec duplication : La tâche v1 a été dupliquée sur p2 et p3 pour pouvoir placer v4, v5, v3 au même moment.

3.2.3 Modèle UET-LCT Le modèle

Le modèle proposé par Papadimitriou et Yannakakis [23] considère toujours des tâches de durée unitaire, mais le coût de communication est donné par 'y > 1. Ce modèle est dénommé UET-LCT (unit execution time - large communication time). Ce modèle convient aux réseaux d'ordinateurs où les processeurs sont rapides et le réseau représente le point d'étranglement du système.

Figure II.10 - Exécution dans le modèle UET-UCT sans et avec duplication

Ordonnancement avec UET-LCT

Dans la figure II-10, le temps de communication entre tâches exécutées sur processeurs distincts est de 2, 5, c'est-à-dire deux fois et demi le temps d'exécution d'une tâche.

Sans duplication : Au temps t = 0, v1 et v2 sont allouées aux processeurs p1 et p2.

Au temps t = 1, on choisit d'allouer v3, v6 et v5 aux processeurs p1, p2 et p3 ainsi les temps de communication entre v1 et v3 , v2 et v6 sont annulés. Tandis que v5 débutera son exécution au temps t = 1 + 1 + 2, 5 = 4, 5 puisqu'il s'exécute sur un processeur différent de son prédécesseur direct.

Au temps t = 2, on choisit d'allouer v4 à p1.

Au temps t = 3, on alloue v7 sur le même processeur que v3 et v4 annulant ainsi les temps de communication.

Au temps t = 4.5, étant donné que les tâches v7 et v5 ont déjà terminées leur exécution, on choisit de lancer v9 sur p1. Il débutera au temps t = 4,5 + 2,5 = 7.

On applique le même principe aux autres tâches.On remarque que p2 est inactif longtemps.

Avec duplication : La tâche v1 uniquement est dupliquée sur p2 pour pouvoir lancer les tâches v3, v5 et v6 au temps 1. Egalement, on a dupliqué v1 et v5 sur p3 pour pouvoir lancer v11 tôt. v9 débute son exécution au temps t = 4, 5 sur p1 puisque la tâche v5 a terminé au temps 2 et v7 a été exécuté sur p1.

On obtient un temps de t = 5,5 au lieu de t = 8 sans duplication.

Figure II.11 - Exécution dans le modèle UET-LCT sans et avec duplication

Jusqu'ici, les coûts des tâches ainsi que les coûts des communications ont été constants. Il existe aussi la possibilité d'avoir des coûts variables.

3.2.4 Modèle SCT Le modèle

Il existe d'autres approches telles que le modèle SCT (small communication time) proposé par Colin et Chrétienne [7]. Dans ce cas, les temps d'exécution sont plus grands que les temps de communication.

Ordonnancement avec SCT

La figure II-12 montre des schémas d'exécution du graphe G avec et sans duplication. Le temps de communication est la moitié de la durée d'une tâche.

Sans duplication : Avec un raisonnement similaire à celui appliqué au modèle précédent, on obtient un temps égal à 5 sans duplication de tâches.

Avec duplication : On choisit de dupliquer la tâche v1 sur p3 pour pouvoir débuter v3 plutôt et réduire les temps d'inactivité de p3. On obtient un temps de t = 4, 5.

Figure II.12 - Exécutions dans le modèle SCT sans et avec duplication

L'intérêt de l'introduction de plusieurs restrictions sur les modèles délai réside dans la possibilité de pouvoir donner des garanties de performances plus fines pour les problèmes d'ordonnancement.

3.3 Le modèle LogP Le modèle

Le modèle LogP [9] a le mérite d'avoir été conçu conjointement par des spécialistes en architectures, en environnements d'exécution et en algorithmique. Ce modèle suppose un nombre fini P de processeurs à mémoire locale. La topologie du réseau n'est pas prise en compte. Les synchronisations sont faites par échange de messages. Le temps de communication considère le coût d'échanges de message pour chaque processeur. Dans le modèle LogP, les coûts de communication sont déterminés à travers les paramètres L, o et g.

Lors de l'envoi d'un message le processeur expéditeur ne peut pas calculer pendant un période de temps, ce surcoût est dénoté par o (overhead). La réception d'un message coûte aussi un temps de calcul o du processeur récepteur.

Il existe aussi un intervalle de temps minimal entre l'envoi de deux messages par le même processeur, cet intervalle est dénoté par g (gap). Cet intervalle de temps doit aussi être respecté lors de la réception des messages.

Figure II.13 - Exemple des paramètres LogP

La latence L(latency) est le maximum entre le temps d'envoi d'un message (achèvement de l'opération d'envoi) et le temps de réception de ce message (début de l'opération de réception), sur des conditions de communication normales.

Pour éviter la congestion du réseau, au plus partie supérieure de L/g messages peuvent transiter simultanément. Dans la Figure II.13 nous illustrons les paramètres du modèle LogP, "les tâches noires" sont dues aux surcoûts de transmission et de réception. Un carré gris représente la latence. Entre deux communications consécutives il existe un intervalle de taille au moins g. La définition première de LogP a été donnée pour de petits messages.

Avec de gros messages, la latence peut devenir négative, le premier mot du message peut arriver avant le départ de son dernier mot. Quelques variations plus générales du modèle LogP ont été proposées par Hwang et al. [2, 11].

Ordonnancement avec LogP

La figure II-14 exhibe deux ordonnancements sous le modèle LogP sans duplication. Dans le premier (à gauche) o = 0, 125 et L = 0, 25 du temps d'exécution d'une tâche, le paramètre g est au plus 1. Dans le deuxième exemple (à droite) nous utilisons les mêmes valeurs pour o et L cependant g = 1.5.

Dans le premier cas, on choisit d'ordonnancer v1 et v2 sur les processeurs p1 et p2 respectivement. v5 débute son exécution au temps t = 1 + 0, 125 puisqu'il utilise un surcoût de 0, 125 pour l'envoi du message à v3.

La tâche v6 débute au temps 1. La tâche v11 débutera au temps t = 1 + 0, 125 + 1 + 0, 125 + 0, 25 + 0, 125 = 2, 625 tenant en compte le temps de transmission du message venant de v5, le temps de traitement de l'envoi par v5 et le temps traitement de la réception par v11. v3 débute à son tour sur p3 au temps t = 1 +0, 125 +0, 25 +0, 125 = 2 tenant en compte le temps de transmission du message, le temps de traitement de l'envoi par v1 et le temps de traitement de réception du message par v3. Les tâches v4, v7 et v9 sont allouées au processeur p3 mais la dernière devra traiter la réception du message de v5 au coût 0, 125. v8 et v10 sont allouées à p1.

La figure de droite s'explique pareillement à la seule différence qu'il faut considérer g = 1, 5.

3.4 Le modèle BSP Le modèle

Plus qu'un modèle d'exécution, BSP [15, 18, 30] (Bulk Synchronous Parallel) est un modèle de programmation. Son objectif est de fournir un cadre permettant de concevoir facilement des algorithmes portables et efficaces. Le modèle BSP n'est pas basé sur des modèles de machines existantes,

Figure II.14 - Ordonnancement sous le modèle LogP

mais il convient aux machines MIMD. L'idée principale du modèle BSP est la séparation du calcul de la communication. Ses concepts de base sont la super-étape (de l'anglais super-step) et la synchronisation.

L'application est divisée en super-étapes. Tous les processeurs commencent une super-étape au même instant. Entre deux super-étapes, il existe une étape de synchronisation. Les données communiquées lors d'une super-étape seront disponibles aux processeurs destinataires au début de la super-étape suivante.

Les trois paramètres utilisés afin de décrire le modèle sont p, l et g. Nous utilisons les mêmes notations que celles utilisées dans [18], malgré l'utilisation de g auparavant pour la description du modèle LogP. Ce choix est motivé par la standardisation de ces notations pour les deux modèles. p le nombre de processeurs de la machine; l le coût d'une synchronisation globale; g le temps de transport d'un mot par le réseau. Autrement dit, 1/g est la bande passante. Le modèle original proposé par Valiant [30] introduit un paramètre qui représente la périodicité d'une synchronisation. Dans son modèle, une vérification globale est effectuée après chaque période de L unités de temps. Elle sert à déterminer si la super-étape a été achevée sur tous les processeurs. Dans la version du modèle présentée par McColl [28] il n'y a pas de référence à la périodicité. Cette approche a été probablement choisie parce que dans les machines courantes la périodicité peut être aussi petite que le coût de synchronisation. C'est cette approche que nous avons adoptée dans ce document. Pour pouvoir estimer le temps d'une application BSP nous introduisons les terminologies suivantes :

- pi processeurs de la machine (0 i < p);

- Wis coût des calculs exécutés par le processeur pi au cours de la super-étape s;

- hs i - désigne le maximum du nombre de mots reçus (ou envoyés) par le processeur pi au cours de la super-étape s.

Une h-relation est une opération d'échanges de données point à point entre les processeurs, où chaque processeur peut envoyer et recevoir au plus h mots. L'estimation du temps total d'un programme BSP est obtenue en sommant les temps de ses super-étapes. Les démarches pour obtenir une application efficace dans le modèle BSP sont donc : équilibrer la charge de calcul entre les processeurs au cours de chaque super-étape, équilibrer les communications au cours d'une super-étape (éviter les congestions) et finalement minimiser le nombre de super-étapes.

Pour les schémas d'exécution dans le modèle BSP nous avons choisi une représentation explicite des communications entre les processeurs (figure II-15 à gauche)2 et représentation implicite des communications entre les processeurs entre les super-étapes. Les communications entre les processeurs sont représentés comme une barrière grise ( correspondant à la h-relation ) qui se trouve juste avant la synchronisation ( barrière noire dans la figure II-15 à droite ). De cette façon les communications

2Les flèches représentent les données envoyées d'un processeur à l'autre

restent implicites3. Ordonnancement avec BSP

Dans l'exemple, le temps pour achever une h-relation est 0,5 du temps d'exécution d'une tâche. Le temps de synchronisation est 0,25.

On alloue les tâches v1 et v2 aux processeurs p1 et p2. On choisit d'exécuter les tâches v3, v5, v6 sur les processeurs p1, p2, p3 respectivement.

Dès que les tâches v1 et v2 ont terminées leur exécution, une h-relation est effectuée puisque les données doivent être transmises de p1 à p2, de p2 à p3.

Tous les processeurs vont donc débuter cette super-étape. Elle sera suivie par une étape de synchronisation pour s'assurer que les processeurs ont terminés les communications au même instant. Egalement, il y aura une h-relation après l'exécution des tâches v7 et v10 pour pouvoir transférer les données entre les processeurs.

Figure II.15 - Schéma d'exécution dans le modèle BSP

Conclusion

Dans ce chapitre on a vu comment représenter des applications parallèles en utilisant des graphes de précédence et de flots de données. Un autre plus général que nous adopterons par la suite a été présenté : le graphe de tâches. Il contient les caractéristiques des deux graphes précédemment cités mais de manière plus fine. Après avoir présenté de manière succinte les modèles d'ordonnancement avec délai et sans délai de communications sur des graphes, nous avons décrit les modèles d'exécution les plus souvent employés qui donnent une prédiction sur le temps d'exécution parallèle. Les modèles sans délais de communication sont très loin de la réalité concernant les machines à mémoire distribuée alors que les modèles avec délai sont raisonnablement plus proches de la réalité bien qu'ils ne tiennent pas compte des paramètres comme le débit du processeur, la latence de communication entre des processeurs distants. Les modèles LogP et BSP par contre tiennent compte de ces paramètres en plus du nombre d'unités de calcul. Le second utilise également un synchroniseur général après les super-étapes de calcul.

Il ressort des modèles d'exécution qu'on obtient un temps optimal lorsque l'on néglige les temps de communication, mais on s'éloigne du temps optimal lorsque l'on tient compte des délais de communication. Le principe de la duplication de tâches est souvent employée pour réduire les temps d'inactivité des processeurs. Jusqu'ici, les modèles utilisés négligent des éléments importants comme la congestion du réseau pourtant présents dans une architecture MIMD à mémoire distribuée telle que les grappes

3Les communications sont cachées

hétérogènes dans la cadre de l'ordonnancement. Dans le chapitre suivant, nous proposons un modèle d'ordonnancement sous ces architectures.

Chapitre III

GRAPPES HETEROGENES et

ORDONNANCEMENT

N

otre travail a pour objectif de proposer un ordonnancement des tâches issues d'une application parallèle sur une grappe hétérogène en tenant compte de toutes les ressources informatiques présentes. En d'autres termes, étant donnés, l'application parallèle traduite en graphe de tâches et la grappe

hétérogène, il s'agira pour nous de trouver un bon placement des tâches.

Il convient donc de bien maîtriser d'une part notre architecture MIMD donc de cerner ses caractéristiques en termes de ressources logicielles( les bibliothèques de communication ) et matérielles ( le réseau d'interconnexion, les noeuds, les équipements réseaux etc.) et d'autre part le graphe de tâches (les précédences, les volumes de données etc..) pour répartir efficacement les tâches de notre application entre les différentes unités de traitement et de traiter chacune en parallèle.

1 Eléments de coût

Les grappes hétérogènes impliquent de prendre en compte plusieurs facteurs de coût pour une bonne exploitation. Parmi ces facteurs, on peut citer les stations de travail, les éléments d'interconnexion entre eux, la technologie du réseau utilisé et le système d'exploitation et la pile réseau.

1.1 Les stations de travail

Les machines constituants la grappe peuvent être des machines constituées de plusieurs processeurs ou des monoprocesseurs. Ces machines peuvent avoir des mémoires de capacités de stockage différentes(256 Mo, 128 Mo etc..).

1.2 Les équipements réseau

Les équipements permettant de faire transiter les données entre les stations de travail peuvent être :

- Les commutateurs

- Les routeurs

- Les concentrateurs

1.2.1 Les commutateurs

Ce sont des équipements de couche 2 du modèle OSI qui filtrent, acheminent et font circuler les trames ( figure III-1 ) en fonction de l'adresse de destination de chaque trame.

Les commutateurs utilisent des adresses MAC pour orienter les communications réseau via leur matrice de commutation vers le port approprié et en direction du noeudde destination. La matrice de commutation désigne les circuits intégrés et les éléments de programmation associés qui permettent de contrôler les chemins de données par le biais du commutateur. Pour qu'un commutateur puisse connaître les ports à utiliser en vue de la transmission d'une trame de monodiffusion, il doit avant tout savoir quels noeuds existent sur chacun de ses ports.

Un commutateur détermine le mode de gestion des trames de données entrantes à l'aide d'une table d'adresses MAC. Il crée sa table d'adresses MAC en enregistrant les adresses MAC des noeuds connectés à chacun de ses ports.

Dès que l'adresse MAC d'un noeudspécifique sur un port spécifique est enregistrée dans la table d'adresses, le commutateur peut alors envoyer le trafic destiné au noeudvers le port mappé à ce dernier pour les transmissions suivantes.

Lorsqu'un commutateur reçoit une trame de données entrantes et que l'adresse MAC de destination ne se trouve pas dans la table, il transmet la trame à l'ensemble des ports, à l'exception du port sur lequel elle a été reçue. Dès que le noeudde destination répond, le commutateur enregistre l'adresse MAC de ce dernier dans la table d'adresses à partir du champ d'adresse source de la trame. Dans le cadre de réseaux dotés de plusieurs commutateurs interconnectés, les tables d'adresses MAC enregistrent plusieurs adresses MAC pour les ports chargés de relier les commutateurs qui permettent de voir au-delà du noeud. En règle générale, les ports de commutateur utilisés pour connecter entre eux deux commutateurs disposent de plusieurs adresses MAC enregistrées dans la table d'adresses MAC.

Figure III.1 - Trame ethernet

Ils transmettent des trames Ethernet sur un réseau selon différents modes : commutation Store and Forward (stockage et retransmission) ou cut-through (direct).

Commutation store and forward. Lorsque le commutateur reçoit la trame, il stocke les données dans des mémoires tampons jusqu'à ce qu'il reçu l'intégralité de la trame. Au cours de ce processus de stockage, le commutateur recherche dans la trame des informations concernant sa destination. Dans le cadre de ce même processus, le commutateur procède à un contrôle d'erreur à l'aide du contrôle par redondance cyclique (CRC) de l'en-queue de la trame Ethernet. Le contrôle par redondance cyclique (CRC) a recours à une formule mathématique fondée sur le nombre de bits (de uns) dans la trame afin de déterminer si la trame reçue possède une erreur. Une fois l'intégrité de la trame confirmée, celle-ci est transférée via le port approprié vers la destination. En cas d'erreur détectée au sein de la trame, le commutateur ignore la trame. L'abandon des trames avec erreurs réduit le volume de bande passante

consommé par les données altérées.

Commutation cut-through. Dans le cas de la commutation cut-through, le commutateur agit sur les données à mesure qu'il les reçoit, même si la transmission n'est pas terminée. Le commutateur met une quantité juste suffisante de la trame en tampon afin de lire l'adresse MAC de destination et déterminer ainsi le port auquel les données sont à transmettre. L'adresse MAC de destination est située dans les six premiers octets de la trame à la suite du préambule. Le commutateur recherche l'adresse MAC de destination dans sa table de commutation, détermine le port d'interface de sortie et transmet la trame vers sa destination via le port de commutateur désigné. Le commutateur ne procède à aucun contrôle d'erreur dans la trame.

Il existe deux variantes de la commutation cut-through:

- Commutation fast-forward : ce mode de commutation offre le niveau de latence le plus faible. La commutation fast-forward transmet un paquet immédiatement après la lecture de l'adresse de destination. Du fait que le mode de commutation fast-forward entame la transmission avant la réception du paquet tout entier, il peut arriver que des paquets relayés comportent des erreurs. Cette situation est occasionnelle et la carte réseau de destination ignore le paquet défectueux lors de sa réception. En mode fast-forward, la latence est mesurée à partir du premier bit reçu jusqu'au premier bit transmis. La commutation fast-forward est la méthode de commutation cut-through classique.

- Commutation fragment-free : en mode de commutation fragment-free, le commutateur stocke les 64 premiers octets de la trame avant la transmission. La commutation fragment-free peut être considérée comme un compromis entre la commutation store andforward et la commutation cut-through. La raison pour laquelle la commutation fragment-free stocke uniquement les 64 premiers octets de la trame est que la plupart des erreurs et des collisions sur le réseau surviennent pendant ces 64 premiers octets. La commutation fragment-free tente d'améliorer la commutation cut-through en procédant à un petit contrôle d'erreur sur les 64 premiers octets de la trame afin de s'assurer qu'aucune collision ne s'est produite lors de la transmission de la trame. La commutation fragment-free offre un compromis entre la latence élevée et la forte intégrité de la commutation store and forward; et la latence faible et l'intégrité réduite de la commutation cut-through.

La commutation cut-through est bien plus rapide que la commutation store and forward, puisque le commutateur n'a ni à attendre que la trame soit entièrement mise en mémoire tampon, ni besoin de réaliser un contrôle d'erreur. En revanche, du fait de l'absence d'un contrôle d'erreur, elle transmet les trames endommagées sur le réseau. Les trames qui ont été altérées consomment de la bande passante au cours de leur transmission. La carte de réseau de destination ignore ces trames au bout du compte.

De plus, les commutateurs peuvent être symétriques ou asymétriques. La commutation symétrique offre des connexions commutées entre les ports dotés de la même bande passante, notamment tous les ports 100Mbits/s ou 1000Mbits/s. Un commutateur de réseau local asymétrique assure des connexions commutées entre des ports associés à des bandes passantes différentes, par exemple entre une combinaison de ports de 10Mbits/s, 100Mbits/s et 1000Mbits/s.

Un commutateur asymétrique dispose donc de débit différents sur chacun de ses ports.

1.2.2 Les concentrateurs

Ce sont des équipements réseau d'interconnexion de couche 1 du protocole OSI qui contrairement aux switchs sont moins intelligents. Ils n'ont aucune fonction de commutation, de traitement de données. Lorsqu'ils reçoivent un signal (0 ou 1), ils ne savent à qui transmettre l'information; ils propagent l'information sur tous les ports y compris le port de réception.

1.2.3 Les routeurs

Cet équipement de couche 3 du protocole OSI maintient une table de routage contenant des routes de sortie vers d'autres réseaux. Lorsqu'il recoit message, son rôle est choisir le meilleur chemin pour parvenir au destinataire. Ce choix s'éffectue à l'aide des algorithmes de routage très complexes : la route la plus courte n'est pas forcément la meilleure. Ce qui importe en réalité, c'est la somme des temps de transit pour une destination donnée qui, elle même, est proportionnelle à l'importance du traffic et au nombre de messages qui attendent d'être transmis sur les différentes lignes.

1.3 Technologie réseau

Les communications dans un réseau local commuté surviennent sous trois formes : monodiffusion, diffusion et multidiffusion :

- Monodiffusion : communication dans laquelle une trame est transmise depuis un hôte vers une destination spécifique. Ce mode de transmission nécessite simplement un expéditeur et un récepteur. La transmission monodiffusion est la forme de transmission prédominante adoptée sur les réseaux locaux et sur Internet. HTTP, SMTP, FTP et Telnet sont des exemples de transmission monodiffusion.

- Diffusion : communication dans laquelle une trame est transmise d'une adresse vers toutes les autres adresses existantes. Un seul expéditeur intervient dans ce cas, mais les informations sont transmises à tous les récepteurs connectés. La transmission par diffusion est un incontournable si vous envoyez le même message à tous les périphériques sur le réseau local. Un exemple de diffusion est la requête de résolution d'adresse que le protocole ARP (Address Resolution Protocol) transmet à tous les ordinateurs sur un réseau local.

- Multidiffusion : communication dans laquelle une trame est transmise à un groupe spécifique de périphériques ou de clients. Les clients de transmission multidiffusion doivent être membres d'un groupe de multidiffusion logique pour recevoir les informations. Les transmissions vidéo et vocales employées lors de réunions professionnelles collaboratives en réseau sont des exemples de transmission multidiffusion.

Selon chacune des formes, les liens peuvent être de latence et débit différents. Typiquement, si on a trois machines M1 , M2 , M3 reliées via un commutateur S1, le temps de transmission de M1 à M2 peut être différent du temps de M1 à M3 par exemple. Cela peut être dû aux congestions intervenues sur chaque liaison ou même aux performances des machines.

1.4 Système d'exploitation et pile réseau

Les ordinateurs constituants la grappe peuvent avoir des systèmes d'exploitation différents avec une version précise.Comme exemple, Ubuntu 9.04, Windows Vista, Solaris 9 etc.. Ces systèmes sont constitués de module de gestion des communications. Dans la suite nous donnons une description générale de la pile réseau utilisée pour les communications entre deux hôtes.

Dans un système monoprocesseur, la plupart des communications inter-processus supposent l'existence d'une mémoire partagée. Dans le cas d'une grappe, le mémoire est distribuée et les communications se font par échange de messages. Quand le processus A veut communiquer avec le processus B, il commence par élaborer un message dans son propre espace d'adressage. Il exécute ensuite un appel système qui va prendre le message et l'envoyer à B via le réseau. L'émetteur et le récepteur doivent être en accord sur de nombreuses choses; depuis les détails de bas niveau de la transmission des bits jusqu'à ceux de plus haut niveau de la représentation des données. Pour résoudre plus facilement ces problèmes, l'ISO (organisation internationale de Normalisation) a défini un modèle de référence qui identifie clairement les différents niveaux d'une communication. Ce modèle est le modèle OSI (Open Systems Interconnection) qui comporte sept couches:

1. la couche physique : c'est la couche la plus basse. Elle est concernée par la normalisation des interfaces électriques et mécaniques et des signaux.

2. la couche liaison : Son rôle primordial est de détecter et traiter les erreurs dans les réseaux de communication.

3. la couche réseau : Son rôle est de choisir le meilleur chemin pour faire transiter un message.

4. la couche transport : Son rôle est de gérer le service de connexion fiable entre l'expéditeur et le destinataire.

5. la couche session: C'est une version enrichie de la couche transport. Elle fournit des dialogues de contrôle pour mémoriser les connexions en cours ainsi que des mécanismes de synchronisation.

6. la couche présentation : Elle s'occupe de la signification des bits.

7. la couche application: c'est la couche la plus haute. Elle comporte un ensemble de protocoles divers pour gérer des applications utilisateurs comme le transfert de fichiers.

Dans ce modèle, la communication est partagée en ces sept couches. L'ensemble des protocoles utilisés est appelé suite de protocoles ou pile de protocoles. Quand le processus A de la machine 1 veut communiquer avec le processus B de la machine 2, il élabore un message et passe ce message à la couche application de la machine 1. Le logiciel de la couche application ajoute une en-tête au début du message et passe le message qui en résulte à la couche présentation au travers de l'interface des couches 6/7. La couche présentation rajoute son en-tête et passe le résultat à la couche session et ainsi de suite. Certaines couches ne se contentent pas d'ajouter des informations en début du message, elles en ajoutent également à la fin. Quand le message arrive en bas de la pile, la couche physique transmet le message qui ressemble alors à ce qui est décrit à la figure III.2.

Quand le message arrive sur la machine 2, il remonte les couches et chacune de celles-ci prend et examine l'en-tête qui lui correspond. Le message finit par arriver au récepteur, c'est à dire que la machine 2 peut alors répondre en suivant le chemin inverse.

Si on examine encore notre cas de tout à l'heure entre la machine 1 et la machine 2, l'existence des en-têtes implique une perte d'éfficacité considérable. Chaque fois qu'un message est envoyé, il doit être traité par une demi douzaines de couches. Chacune d'entre elles génère et ajoute un en-tête dans le chemin descendant ou bien retire et traite dans le chemin ascendant. Tout ce travail prend du temps. La perte d'éfficacité due à la gestion de la pile de protocoles n'est pas négligeable pour un système qui utilise un réseau local. On perd réellement de temps UC1 pour cette gestion que le débit effectif est souvent une fraction de la capacité nominale du réseau.

Cette description est variable selon des systèmes d'exploitation.

'Unité centrale

Figure III.2 - Un message classique tel qu'il transite sur le réseau

Nous voyons donc que chacun des éléments de coût ci-haut sont non uniformes et complexes dans leur fonctionnement. Chacun d'eux induit des surcoûts considérables.

Les modèles d'ordonnancement traditionnels présentés au chapitre précédent ne sont pas réellement adaptés aux grappes hétérogènes puisqu'ils ne tiennent pas compte d'un grand nombre de paramètres cités ci-haut. Notamment, le coût de gestion de la pile de protocoles est toujours considéré comme négligeable, la congestion du réseau est négligée (ces modèles supposent généralement que le réseau est parfait). Ils nécessitent par conséquent d'être plus affinés. Nous développons dans la suite un modèle plus fin de placement des tâches sur les ressources de calcul sur notre architecture. Nous donnons également une modélisation de cette dernière.

2 Proposition d'un modèle d'ordonnancement sur les grappes hétérogènes

Notre système d'ordonnancement comprend : le graphe de tâches, la grappe hétérogène et l'ordonnancement proprement dit dans lequel des critères de performance et de validité seront détaillés. Ces composantes sont présentées plus formellement.

2.1 Modélisation de l'architecture hétérogène

Notre environnement hétérogène peut donc être modélisé par un graphe Gr = (Vr, Er) que nous appellons graphe de la grappe. Vr = {P1, P2, ..., Pm} est l'ensemble des unités de calcul. Er est l'ensemble des liens de communication entre les noeuds.

1. m noeuds Pi, 1 < i < m caractérisés par: - Leur puissance Si,

- Leur capacité mémoire Mi,

- L'impact du protocole réseau Ri.

2. Chaque arc (i, j) de Er connectant deux noeuds Pi et Pj de Vr est caractérisé par: - Sa latence lij,

- Son débit dij.

2.2 Graphe de tâches.

Les caractéristiques de notre application parallèle sont définis comme les 4-uplets (T,<,D,A) ainsi qu'il suit :

- T=t1,...,tn qui est l'ensemble des tâches à exécuter.

- < est l'ordre partiel défini sur T qui spécifie les contraintes sur l'ordre de précédence entre les tâches. C'est à dire ti < tj veut dire que ti doit être complètement exécutée avant que tj ne débute son exécution.

- D est une matrice n x n de données communiquées entre les tâches, où dataij ~ 0 est le volume des données réquis à transmettre de la tâche ti à la tâche tj, 1 < ti, tj < n.

- A un vecteur de taille n qui représente l'ensemble des coûts des chaque tâche. C'est à dire, cij > 0 est le coût en calcul de la tâche ti sur le processeur Pj, 1 ti, tj n.

Le graphe de tâche (T,E) est acyclique où E est l'ensemble des arcs.

Un arc (ti,tj) entre deux tâches ti et tj spécifie la relation de précédence entre ti et tj. A chaque sommet ti est associé son temps de calcul qui représente le nombre d'instructions ou d'opérations présentes dans la dite tâche. A Chaque arc (ti,tj) connectant les tâches ti et tj est associé la taille des données dataij, c'est à dire la taille du message de ti à tj.

Ordonnancer les tâches revient donc à répartir les tâches sur la grappe en respectant les contraintes de précédence entre elles.

2.3 L'ordonnancement.

Un ordonnancement f prend en entrée: - Le graphe de grappe Gr = (Vr,Er),

- Le graphe de tâches G = (V, E) Plus formellement,

- f : V -? Vr X [0,00) Ti -? (Pj,s)

f(Ti) = (Pj, t) signifie que la tâche Ti sera traitée par le processeur Pj au temps t.

- F inTim est le temps de fin d'exécution de la tâche Ti sur le processeur Pm.F inTim = sim + cim sim est son temps de début d'exécution sur le processeur Pm.

2.4 Modéle des communications

Une tâche est considérée comme prête si tous ses prédécesseurs ont terminé leur éxécution et que toutes les données utiles calculées par ses prédécesseurs ont été acheminées dans la mémoire locale du processeur où vont avoir lieu les calculs.

Deux tâches d'un arc du graphe peuvent être allouées au même processeur ou non. Lorsque nous sommes dans le premier cas, cela veut dire que le coût de communication de données est identique à celui d'un accès à la mémoire locale puisque les données nécéssaires à l'exécution des tâches sont présentes. Ce coût est négligeable et est considéré égal à zéro. Lorsque nous sommes dans le deuxième cas, le coût de communication de données est le temps de transfert des données nécessaires à la tâche seconde pour débuter son exécution.

Plus formellement, Si une tâche Ti ( ordonnançée sur Pm ) doit communiquer les données à l'un de ses successeurs Tj ( ordonnançée sur Pn ), le coût est modéliser par :

1

0 si Pm = Pn

C(Tim, Tjn) = lmn + dataij × 1

dmn sinon.

La date de début d'exécution de Tj est donc sjn = F inTim + C(Tim, Tjn).

Les problèmes NP-complet sont des problèmes qui sont très difficilement solubles en temps polynomial. Il ya un bon nombre de problèmes qui sont équivalents en complexité et forment la classe des problèmes NP-complets. Cette classe inclut plusieurs problèmes classiques de combinatoire, de théorie de graphe, et d'informatique comme le problème du voyageur de commerce, le problème du circuit hamiltonien, le problème d'affectation etc. Les meilleurs algorithmes connus pour ces problèmes peuvent avoir une complexité exponentielle avec certaines entrées. La complexité exacte de ces problèmes NP-complets reste un problème ouvert en informatique théorique. Soit tous ces problèmes ont des solutions en temps polynomial ou aucun d'entre eux n'a une telle solution.

Il a été prouvé que le problème d'ordonnancement[6] d'un ensemble de m tâches sur n processeurs identiques est NP-Complet en tenant compte des communications entre les processeurs. Nous avons choisi d'aller vers une solution heuristique permettant d'avoir un bon ordonnancement.

2.5 Idée Générale

Les points suivants constituent l'idée générale à appliquer lorsque l'on doit effectuer une instance d'ordonnancement f comme décrit précédemment.

1. Exécuter les tâches les plus longues sur les processeurs les plus rapides.

2. Exécuter les tâches qui communiquent beaucoup sur les processeurs disponibles les plus proches.2

3. Exécuter les tâches qui communiquent un gros volume de données sur des processeurs connectés sur des gros réseaux.

4. On exécute Ti sur Pj si :

- le temps de transfert des données de Ti sur Pj est minimal

- Pj est libre à cet instant

- cij est «acceptable »

La décision d'exécuter une tâche ti sur un processeur Pj à un instant donné est donc motivée par: - L'ensemble des tâches prêtes

- Le coût des tâches cij

- Le surcoût des communications

- L'état des processeurs

Le chapitre suivant illustrera sur un exemple cette heuristique.

2Les processeurs interconnectés par des liens de latence faible

Chapitre IV

EVALUATION DU MODELE SUR UNE

APPLICATION

Ce chapitre est la phase la plus pratique de notre travail. Il est constitué du déploiement de la grappe, de l'implémentation de l'ordonnancement d'un exemple sur cette grappe et du calcul des performances d'une réseau (latence, débit) d'une part et d'autre part de l'analyse des performances de l'application sur la grappe. Nous commencerons par présenter notre grappe, ensuite nous calculerons ses caractéristiques comme décrit dans le modèle, et par la fin nous analyserons les performances d'une application parallèle sur la grappe.

1 Présentation de l'architecture de notre grappe

Notre grappe est constituée de cinq stations de travail, reliées par un switch de 12 ports. La figure IV.1 l'illustre clairement. Pour le déploiement de notre grappe, des outils ont été installés à la base. - Nous avons installé un gestionnaire de tâches : OAR.

- le service NIS1 : qui a pour rôle de distribuer les informations sur les utilisateurs et même sur les postes à travers toute la grappe. Ainsi, tout utilisateur ayant un compte sur le serveur NIS pourra se logger sur n'importe quelle machine de la grappe.

- Le service NFS2 : On l'utilise en corrélation avec le serveur NIS pour distribuer le répertoire utilisateur sur les autres machines. Ainsi, tous les répertoires utilisateurs sur le serveur NFS seront accessibles sur n'importe quelle machine de la grappe.

- Le service SSH nécessaire pour se logger à distance.

- La bibliothèque de communications MPICH2 qui nous permettra de paralléliser les applications. L'installation de toutes ces composantes est précisée en annexe. Les caractéristiques des stations de travail sont récapitulées dans le tableau ci-dessous :

1network information service 2network file system

Figure IV.1 - Notre grappe

 

Processeur

Mémoire

Nom/adresse IP

SE

Machine1

Pentium 4, 3GHZ

512Mo

host1.labomaster/192.168.12.1

Debian 4.0

Machine2

Intel Celeron, 2GHZ

256Mo

host2.labomaster/192.168.12.2

Debian 4.0

Machine3

Pentium Dual @2GHZ

2Go

server.labomaster/192.168.12.3

Ubuntu 9.4

Machine4

Pentium 4,3.40GHZ

1Go

host3.labomaster/192.168.12.4

Debian 5.0

Machine5

Pentium 4,3GHZ

1Go

host4.labomaster/192.168.12.5

Debian 5.0

La machine 3 représente à la fois le serveur OAR, le serveur NIS, le serveur NFS et le serveur DNS. MPICH2 a été installé sur ce poste et est dupliqué via NFS sur les autres postes. Chacune de ces machines sont interconnectées par un réseau fast Ethernet 100Mbits/s. D'après notre modèle, une grappe hétérogène est modélisée par un graphe où les sommets sont les stations de travail caractérisées par la puissance du processeur, la mémoire et l'impact de la pile réseau. Dans le suite, nous décrirons comment nous avons estimé la troisième caractéristique.

2 Calcul des caractéristiques des noeuds du graphe de grappe

Lorsqu'une trame sort ou entre dans un hôte, elle traverse toutes les couches de la pile réseau et cela engendre un coût non négligeable.

2.1 Les surcoûts engendrés par la pile réseau relatifs à chaque station de travail

Il a été difficile de trouver un outil pour évaluer l'impact du protocole réseau; nous avons écrit un algorithme basé sur les sockets pouvoir évaluer les coûts engendrés par chaque ordinateur. Cet algorithme est basé sur le modèle client/serveur avec pour protocole UDP3 où le client envoie un message de 8 octets au serveur qui est déjà lançé. Ici le client et le serveur sont sur un même poste. Le code que nous avons écrit est le suivant.

CODE DU CLIENT

3User Datagram Protocol

#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <sys/un.h> #include<time.h>

int main (int argc, char* argv[]) {

struct timeval start,m;

struct sockaddr_in id; char s[3];

int id_socket,tempo,envoi,i=1,argument;

int erreur;

id_socket=socket(AF_INET,SOCK_DGRAM,0);

if (id_socket<0)

{perror("\nErreur dans la création du socket");

exit(1);

}

else

printf("\n socket : OK"); id.sin_family=AF_INET; id.sin_addr.s_addr=htonl(INADDR_ANY);

id.sin_port=htons(333); tempo=sizeof(id);

argument=atoi(argv[1]); while(i<=argument)

{

gettimeofday(&start,NULL); envoi=sendto(id_socket,&start,sizeof(start),0,(struct sockaddr*)&id,tempo);

i++;

sleep(1);

}

erreur=close(id_socket); exit(0);

return 0;

}

CODE DU SERVEUR

....

....

#define minim(a,b) ((a)<(b)?a:b)
#define maxim(a,b) ((a)>(b)?a:b)

int main (int argc, char* argv[]) {

id_de_la_socket=socket(AF_INET,SOCK_DGRAM,0);

if (id_de_la_socket<0)

{perror("\nErreur dans la création du socket");

exit(1);

}

else

printf("\n socket : OK"); is.sin_family=AF_INET; is.sin_addr.s_addr=htonl(INADDR_ANY);

is.sin_port=htons(333); tempo=sizeof(is);

erreur=bind(id_de_la_socket,(struct sockaddr*)&is,sizeof(is));

if (erreur<0)

{

perror("\nserver: bind\n"); exit(1);

}

else

printf("\nbind : OK\n"); printf("\n==NbrEnvoi=====MinRTT==================MaxRTT================MoyenneRTT\n"); max=0;

min=1000000;

argument=atoi(argv[1]); while(i<=argument)

{//printf("%d",i);

reception=recvfrom(id_de_la_socket,&start,sizeof(start),0,(struct sockaddr*)&is,&tempo); gettimeofday(&end,NULL);

res=(end.tv_sec-start.tv_sec)*1000000 + (end.tv_usec-start.tv_usec);

min=minim(min,res);

max=maxim(max,res);

moy=moy+res;

printf("Temps mis=%ld microsecondes \n",res);

i++;

}

printf("\n==%d===%d====%d===%1.f\n",(atoi(argv[1])),min,max,(moy/(atoi(argv[1])))); erreur=close(id_de_la_socket);

....

}

Le surcoût de la pile est considéré comme le temps mis par le message en local. Nous avons effectué l'envoi de 1.521.110 messages de 8 octets par machine à des moments différents. Après ces envois, nous avons recueilli les temps mis par le transfert en utilisant la fonction gettimeofdate et nous avons effectué la moyenne pour avoir une estimation fine.

2.2 Tableau récapitulatif et discussion

Nous obtenons donc la tableau ci-dessous qui regroupe tous les impacts correspondants aux différentes machines.

 

Processeur

Mémoire

Coût induit par la pile(microsecondes)

Machine1

Pentium 4, 3GHZ

512Mo

23

Machine2

Intel Celeron, 2GHZ

256Mo

32

Machine3

Pentium Dual @2GHZ

2Go

5

Machine4

Pentium 4,3.40GHZ

1Go

31

Machine5

Pentium 4,3GHZ

1Go

12

On pourrait croire que l'impact du protocole réseau est proportionnel à la vitesse de traitement des processeurs mais la tableau nous présente le contraire. En effet, nous remarquons que les machines 1 et 5 ayant les mêmes vitesses de traitement induisent des coûts tout à fait différents. Celui de la machine 1 est à peu près le double de celui de la machine 5. D'autre part, la machine 4 ayant une vitesse d'exécution supérieure à celles des machines 1 et 5 induit un coût qui est presque la somme des coûts relatifs aux machines 1 et 2. Ceci nous amène à penser que les raisons plausibles sont liées aux activités du processeur au moment du calcul et à la gestion du protocole réseau par le système d'exploitation puisqu'on note que les systèmes d'exploitation sont différents. Le système d'exploitation aurait passer la main à un autre processus différent du notre pour un temps.

3 Calcul des caractéristiques des arcs du graphe de grappe

Pour évaluer les latences des liens, nous avons également écrit un programme basé sur les sockets tandis que pour évaluer les débits des liens nous avons utilisé des outils existants.

3.1 Evaluation des latences

Comme nous l'avons dit précédemment, nous avons écrit un programme sur le principe client/serveur basé sur les sockets en utilisant le protocole UDP mais cette fois on calcule le temps d'une requête réponse par le client c'est à dire que le client fait émet un message de 8 octets au serveur et attend la réponse de ce dernier. Il faut noter ici que le client et le serveur sont sur des postes différents. La latence est donc le temps requête/réponse UDP ou le RTT(Round trip time). Le code que nous avons fait est fourni ci-dessous :

Code du client

.... .... #define minim(a,b) ((a)<(b)?a:b)

#define maxim(a,b) ((a)>(b)?a:b)

....

int erreur;

int main (int argc, char* argv[])

{

....

4celui lancé pour exécuter le programme

....

int id_socket,tempo,envoi,i=1,reception;

id_socket=socket(AF_INET,SOCK_DGRAM,0);

if (id_socket<0)

{perror("\nErreur dans la création du socket\n");

exit(1);

}

else printf("\n socket : OK\n");

id.sin_family=AF_INET; id.sin_addr.s_addr=inet_addr("adresse_du_serveur");

id.sin_port=htons(3333); tempo=sizeof(id);

printf("\n==NbrEnvoi=====MinRTT======MaxRTT=====MoyenneRTT\n");

max=0;

min=100000;

argument=argv[1];

while(i<=argument)

{gettimeofday(&start,NULL); envoi=sendto(id_socket,&start,sizeof(start),0,(struct sockaddr*)&id,tempo); reception=recvfrom(id_socket,&end,sizeof(end),0,(struct sockaddr*)&id,&tempo); gettimeofday(&endl,NULL);

res=(endl.tv_sec-start.tv_sec)*1000000 + (endl.tv_usec-start.tv_usec); min=minim(min,res);

max=maxim(max,res);

moy=moy+res;

i++;

//sleep(3);

} printf("\n=====%d======%d====%d====%1.f\n",atoi(argv[1]),min,max,(moy/(atoi(argv[1])))); erreur=close(id_socket);

exit(0);

return 0;

Code du serveur

int main (int argc, char* argv[])

{

struct timeval end,start;

long int res;

int erreur,tempo,id_de_la_socket,reception,n,i=1,envoi; struct sockaddr_in is;

id_de_la_socket=socket(AF_INET,SOCK_DGRAM,0); if (id_de_la_socket<0)

{perror("\nErreur dans la création du socket\n"); exit(1);

}

else

printf("\n socket : OK\n");

is.sin_family=AF_INET;

is.sin_addr.s_addr=htonl(INADDR_ANY); is.sin_port=htons(3333);

tempo=sizeof(is);

erreur=bind(id_de_la_socket,(struct sockaddr*)&is,sizeof(is)); if (erreur<0)

{

perror("\nserver: bind\n");

exit(1);

}

else

printf("\nbind : OK\n");

//gettimeofday(&end,NULL);

argument = atoi(argv[1]);

while(i<=argument)

{

reception=recvfrom(id_de_la_socket,&start,sizeof(start),0,(struct sockaddr*)&is,&tempo); gettimeofday(&end,NULL);

envoi=sendto(id_de_la_socket,&end,sizeof(end),0,(struct sockaddr*)&is,tempo);

i++;

}

erreur=close(id_de_la_socket);

Nous avons effectué l'envoi de 1.521.110 messages de 8 octets par lien à des moments différents. Après chaque envoi, nous avons recueilli les temps mis par le transfert requête/réponse en utilisant la fonction gettimeofdate. Après tous les envois, nous avons effectué la moyenne de tous les résultats trouvés pour avoir une estimation fine. Nous avons obtenu les latences regroupées dans la tableau ci-dessous correspondantes aux liens entre les hôtes. Elles sont exprimées en microsecondes.

 

Machine1

Machine2

Machine3

Machine4

Machine5

Machine1

x

272

107

127

125

Machine2

223

x

266

187

184

Machine3

123

255

x

260

91

Machine4

29

398

127

x

148

Machine5

126

355

100

132

x

La latence d'une machine M1 à une machine M2 n'est pas forcément la même de M2 à M1. Ceci est dû aux performances des processeurs qui sont différentes et au fait que les systèmes d'exploitation gèrent la pile réseau différemment. Il faut noter que le paquet arrive au niveau du commutateur qui étant donné son fonctionnement mettra un temps pour faire transiter le message.

3.2 Evaluation des débits des liens

Pour évaluer les débits des liens nous avons utilisé les outils netperf et iperf. Nous avons utilisé iperf pour confirmer les débits trouvés avec netperf. La syntaxe de la commande avec netperf est :

#netperf -H <adresse de la machine destinatrice> Le resultat est de la forme

Recv Send Send

Socket Socket Message Elapsed

Size Size Size Time Throughput

bytes bytes bytes secs. 10^6bits/sec

On a obtenu les résultats suivants en Mbits/s :

 

Machine1

Machine2

Machine3

Machine4

Machine5

Machine1

x

94

87

94

83

Machine2

94

x

73

94

77

Machine3

65

81

x

90

94

Machine4

87

90

82

x

88

Machine5

86

82

94

82

x

3.2.1 Discussion

Le débit d'une machine M1 à une machine M2 n'est pas forcément le même de M2 à M1. Ceci peut être dû aux différences entre les vitesses de traitement des processeurs et aux charges des processeurs à un moment donné. Si un processeur est trop surchargé par rapport à l'autre, alors il y aura influence sur le débit. Par ailleurs, on voit que les 100 Mbits/s constituant le débit du réseau Fast-Ethernet n'est jamais atteint. On a en moyenne 85.85 Mbits/s. Cela peut être dû au fait qu'il y a des collisions sur le réseau entrainant ainsi des pertes de messages.

4 Programmation de l'application

Nous avons choisi de paralléliser la multiplication d'une matrice A par un vecteur V . 4.1 Algorithme

Le principe est le suivant : Le processus 0 est le processeur maître et détient la matrice et le vecteur. Les autres processus n'ont que le vecteur. Initialement le maître découpe la matrice et envoie une ligne de la matrice aux autres processeurs. Dès que le processeur termine d'exécuter la tâche qui est le produit d'une ligne reçue par le vecteur, il renvoie le résultat au maître. Le maître chaque va tester s'il y a encore une ligne non envoyée et si tel est le cas, il envoie à un processeur libre. Le code est le suivant :

4.2 Code

#define min(a,b) ((a)<(b)?a:b)

void initialiser(double m[SIZE][SIZE])

{

int i,j;

for(i=0;i<SIZE;i++) for(j=0;j<SIZE;j++) m[i][j]=1.0;

}

void maitre(int numprocs)

{

int i,j, sender,row,numsent=0; double a[SIZE][SIZE],c[SIZE]; double r;

MPI_Status status;

initialiser(a);

for(i=1;i<min(numprocs,SIZE);i++)

{

MPI_Send(a[i-1],SIZE,MPI_DOUBLE,i,i,MPI_COMM_WORLD);

numsent++;

}

for(i=0;i<SIZE;i++)

{

MPI_Recv(&r,1,MPI_DOUBLE,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&status); sender=status.MPI_SOURCE;

row= status.MPI_TAG-1;

c[row]=r;

if(numsent<SIZE){ MPI_Send(a[numsent],SIZE,MPI_DOUBLE,sender,numsent+1,MPI_COMM_WORLD);

numsent++;

} else

MPI_Send(MPI_BOTTOM,0,MPI_DOUBLE,sender,0,MPI_COMM_WORLD);

}

}

void esclave()

{

double b[SIZE], c[SIZE];

int i, row, myrank;

double r;

MPI_Status status;

for(i=0;i<SIZE;i++) b[i]=2.0;

MPI_Comm_rank(MPI_COMM_WORLD,&myrank);

if(myrank<=SIZE)

{

MPI_Recv(c,SIZE,MPI_DOUBLE,0,MPI_ANY_TAG,MPI_COMM_WORLD,&status); while(status.MPI_TAG>0)

{

row=status.MPI_TAG-1;

r=0.0;

for(i=0;i<SIZE;i++)

r+=c[i]*b[i];

MPI_Send(&r,1,MPI_DOUBLE,0,row+1,MPI_COMM_WORLD); MPI_Recv(c,SIZE,MPI_DOUBLE,0,MPI_ANY_TAG,MPI_COMM_WORLD,&status);

}

} } int main (int argc, char **argv){

int myrank,p;

MPI_Init (&argc, &argv);

MPI_Comm_rank (MPI_COMM_WORLD, &myrank);

MPI_Comm_size (MPI_COMM_WORLD, &p);

double startwtime = 0.0, endwtime;

char processor_name[MPI_MAX_PROCESSOR_NAME];

int namelen;

MPI_Get_processor_name(processor_name,&namelen);

fprintf(stdout,"Le Processus %d parmi %d est sur %s\n",myrank,p, processor_name); MPI_Barrier(MPI_COMM_WORLD);

if(myrank==0) {startwtime = MPI_Wtime();parent(p);}

else enfant();

MPI_Barrier(MPI_COMM_WORLD);

if(myrank==0)

{endwtime = MPI_Wtime();

printf("TEMPS DE CALCUL = %f\n", endwtime-startwtime);

}

...

Le code séquentiel du même problème est fournit en annexe. Pour calculer son temps d'exécution, il suffit de faire

#time ./executable

Nous avons utilisé MPICH2 pour réaliser cette application. Cependant l'ordonnancement que nous fait est fixée au départ et ne change pas tout au long de l'exécution.

5 Ordonnancement sur la grappe

L'ordonnancement est statique c'est à dire qu'il ne change pas tout au long de l'exécution de l'algorithme. Toutes les machines sont utilisées pour l'ordonnancement. La machine server est la machine sur laquelle s'exécute le premier processus. L'ordre d'ordonnancement est server - host2 - host3 - host4 - host1 : le premier processus s'exécute sur la machine server, le second sur la machine host2, le troisième sur la machine host3, le quatrième sur la host4 et le dernier sur la machine host1. S'il y

a encore des processus, alors on reprend avec la machine server et ainsi de suite. Exemple d'exécution avec 8 processus :

user@labofs:~/Desktop/codes$ mpdtrace // Pour avoir l'ordre d'ordonnancement

server

host2

host3

host4

host1

user@labofs:~/Desktop/codes$mpiexec -n 8 av Le Processus 0 parmi 8 est sur server

Le Processus 2 parmi 8 est sur host3 Le Processus 5 parmi 8 est sur server Le Processus 3 parmi 8 est sur host4 Le Processus 4 parmi 8 est sur host1 Le Processus 7 parmi 8 est sur host3 Le Processus 1 parmi 8 est sur host2 Le Processus 6 parmi 8 est sur host2 TEMPS DE CALCUL = 0.054822

5.1 Résultats et discussion

Nous avons obtenu les résultats suivants avec 5, 6, 8, 10, 12, 15, 20, 25, 30, 32, 40, 50, 100 processus.

Nous avons travaillé sur une matrice de tailles n=100, 1000, 3000, 5000 et 8000. Nous dénotons par T _par le temps parallèle, T_seq le temps séquentiel, Acc l'accélération et Eff l'efficacité.

Le temps de calcul séquentiel pour n=100, 1000, 3000, 5000 et 8000 sont respectivement 0.016 secondes, 0.042 secondes, 0.083 secondes, 0.092 secondes et 0.11 secondes sur la machine 3.

pour n=100 -*

Processus

 

T_par(s)

Acc(T_seq/T_par)

Eff

5

0.69

0.02

0.004

6

0.06

0.26

0.04

8

0.05

0.32

0.04

10

0.07

0.22

0.02

12

0.08

0.20

0.01

15

0.09

0.17

0.01

20

0.14

0.11

0.005

25

0.19

0.08

0.003

30

0.3

0.05

0.001

32

0.36

0.04

0.001

40

0.55

0.029

0.0007

50

1.06

0.01

0.0003

100

6.1

0.02

0.00002

pour n=1000 -*

Processus

 

T_par(s)

Acc(T_seq/T_par)

Eff

5

0.006

7

1.14

6

0.007

6

1

8

0.008

5.25

0.65

10

0.009

4.66

0.46

12

0.0095

4.42

0.36

15

0.0072

5.83

0.38

20

0.0075

5.6

0.28

25

0.3

0.14

0.0056

30

0.42

0.1

0.0033

32

0.5

0.084

0.0026

40

1.1

0.038

0.0009

50

2.4

0.017

0.00035

100

6.29

0.0066

0.00006

pour n=3000 -*

Processus

 

T_par(s)

Acc(T_seq/T_par)

Eff

5

0.004

20.75

4.15

6

0.003

27.66

4.61

8

0.0032

25.93

3.24

10

0.002

41.5

4.15

12

0.0021

39.52

3.29

15

0.0023

36.08

2.40

20

0.0025

33.2

1.66

25

0.003

27.06

1.10

30

0.3

0.27

0.009

32

0.47

0.17

0.005

40

0.7

0.11

0.002

50

2.04

0.040

0.0008

100

3.5

0.023

0.0002

pour n=5000 -*

Processus

 

T_par(s)

Acc(T_seq/T_par)

Eff

5

0.0033

27.8

5.57

6

0.0034

27.05

4.50

8

0.0036

25.5

3.19

10

0.0038

24.21

2.42

12

0.0027

34.07

2.83

15

0.002

46

3.06

20

0.0024

38.33

1.91

25

0.0038

24.21

0.96

30

0.47

0.195

0.006

32

0.473

0.194

0.006

40

0.5

0.184

0.0046

50

3.04

0.030

0.0006

100

5.5

0.016

0.0001

n=8000 -?

Processus

 

T_par(s)

Acc(T_seq/T_par)

Eff

5

0.0036

30.55

6.11

6

0.0037

29.41

4.90

8

0.0038

28.94

3.61

10

0.004

27.5

2.75

12

0.0017

64.70

5.39

15

0.0022

50

3.33

20

0.0024

45.83

2.29

25

0.0038

28.94

1.15

30

0.47

0.23

0.007

32

0.77

0.14

0.004

40

0.6

0.18

0.004

50

4.02

0.027

0.0005

100

7.9

0.013

0.0001

Figure IV.2 - Courbe représentant l'accélération de l'algorithme parallèle

Nous remarquons qu'avec une matrice de taille 100, l'accélération est presque nulle; cela veut dire que l'algorithme parallèle est inutile puisque le temps d'exécution en parallèle est plus grand que le temps séquentiel. Avec une matrice de taille 1000, on constate une amélioration des performances avec des processus allant de 5 à 20 processus. Et on trouve que l'algorithme est efficace avec 5 et 6 processus. Lorsqu'on passe aux tailles 2000, 3000, 8000, on remarque que l'algorithme est plus efficace lorsqu'on parallélise avec 20 ou 25 processus. Aussi, l'algorithme accélère avec 5, 6, 8, 10, 12, 15, 20, 25 processus bien qu'elle ne fournit pas une bonne efficacité dans ces cas. Lorsqu'on excède 25 processus, l'accélération et l'efficacité se dégradent rapidement jusqu'à zéro. En effet, le temps de calcul parallèle est alors considérablement réduit lorsque le nombre de processus augmente ceci les processus passent plus de temps à communiquer qu'à calculer.

Figure IV.3 - Courbe représentant l'efficacité de l'algorithme parallèle

Conclusion

Il n'est pas toujours utile de paralléliser une application car elle peut fournir un temps inférieur au temps séquentiel. C'est le cas dans notre exemple avec la matrice de taille 100. La parallélisation de notre exemple pour les tailles 1000, 3000, 5000 et 8000 améliore le temps séquentiel selon que le nombre de processus ne dépasse pas 25 sinon l'algorithme séquentielle est préférable. Ceci nous amène à dire que dans une grappe hétérogène, augmenter le nombre de processeurs n'améliore pas nécessairement le temps de calcul. En plus, l'hétérogénéité ne permet pas d'avoir des performances stables, elles varient beaucoup. En effet, l'accélération n'implique pas forcément une bonne efficacité. Pour avoir une bonne efficacité sur une telle grappe, il faudrait ordonnancer convenablement en tenant compte de toutes ses caractéristiques et de toutes les caractéristiques de l'application.

Conclusion générale et perspectives

Rappel des objectifs

Le problème d'ordonnancement est un problème complexe. Il est encore plus difficile lorsque l'on veut l'appliquer sur une grappe de ressources non uniformes. Il a été question pour nous dans ce travail de proposer un modèle d'ordonnancement de tâches issues d'une application parallèle sur une grappe de calcul hétérogène. Car il a été constaté que la majorité des travaux sur l'ordonnancement s'applique sur les grappes homogènes c'est à dire des grappes constitués de machines identiques interconnectées par réseau uniforme. Dans certains, des éléments indispensables comme la pile réseau pour évaluer le coût sont négligés. Or les grappes homogènes limitent le passage à l'échelle ce qui n'est pas le cas pour les clusters hétérogènes qui nous permettent d'avoir n'importe quel type de ressources de calcul mis ensemble pour fournir une certaine puissance de calcul. Cependant beaucoup de contraintes liées à l'hétérogénéité existent dans ce type d'architecture puisque les différents modules processeurs/mémoires sont différents, les liens d'interconnexion aussi pour ne citer que ceux-là. Pour parvenir à nos objectifs, nous avons d'abord fait une revue de la littérature; une revue qui devait nous permettre d'une part d'étudier les différents types d'architectures parallèles existantes et leur fonctionnement, d'autre part comprendre les principes et concepts du calcul parallèle ainsi que de l'ordonnancement des tâches. Ensuite, il a été question pour nous d'extraire de la littérature des éléments nécessaires sur ce qui a déjà été fait jusqu'aujourd'hui pour constituer notre modèle de base pour allouer les processeurs aux tâches et leur date de début d'exécution bien sûr sur une grappe quelconque non homogène. Enfin, après avoir installé une grappe de manière matérielle et logicielle nous avons évalué ses performances telles que décrite dans le modèle sur un exemple d'application.

Bilan et évaluation du travail réalisé

Pour une bonne compréhension de ce qui a été fait, il importe que nous présentons d'une part le bilan du travail qui a été réalisé et d'autre part que nous essayons de l'évaluer.

Bilan

Ici, il est question pour nous de revenir sur tout ce qui a été fait tout au long de notre travail. En effet nous avons divisé notre travail en cinq principaux chapitres.

Le premier chapitre traite du calcul parallèle et de l'architecture des grappes de calcul. Il a été question pour nous de décrire les raisons qui incitent à faire du calcul en parallèle et quels sont ses fondements. En effet le calcul parallèle est un moyen pour fournir de la haute puissance de calcul à un prix raisonnable en utilisant des ordinateurs standards. Son efficacité dépend fortement de la programmation sou jacente qui consiste à répartir les tâches sur plusieurs processeurs, à repartir les données des problèmes de grande taille qui satureraient la mémoire d'un seul ordinateur et de recouvrir les calculs et les opérations d'entrées-sorties. Nous avons fait ressortir deux types d'applications : statiques et dynamiques ainsi que deux types de parallélisme explicites et implicites qui sont des notions qui nous ont été utiles dans la suite. Egalement, nous avons distingué les différentes architectures parallèles décrites selon la classification de Flynn et expliqué leurs modes de fonctionnement. De cette taxonomie, nous avons extrait notre architecture qui est la grappe de calcul. Calculer les critères de performances d'une application parallèle qui sont l'accélération et l'efficacité ont fait l'objet de la dernière section de ce chapitre.

Le second chapitre a traité essentiellement des concepts de l'ordonnancement. L'ordonnancement est le fait d'allouer aux processeurs des tâches et la date de début de l'exécution de ces dernières. Il a été question pour nous de présenter comment représenter une application parallèle sous forme de graphe de tâches : les sommets sont les tâches, les arêtes sont les synchronisations entre les tâches. Après avoir défini la notion d'ordonnancement, nous avons présenté les modèles classiques d'ordonnancement et les modèles d'exécution pour ces ordonnancements. Il en est ressorti que pour avoir des performances optimales, les éléments de coût comme le surcoût induit par la pile réseau nécessaire pour une grappe devait être négligée ainsi que la congestion du réseau.

L'objet du troisième chapitre a été de modéliser formellement un ordonnancement sur une grappe hétérogène en tenant compte des éléments de coût tels que les stations de travail qui peuvent avoir des caractéristiques différentes, les éléments d'interconnexion ( concentrateurs, commutateurs, routeurs ) utilisés pour interconnecter les stations de travail qui ont des modes de fonctionnement distincts l'un de l'autre, la pile réseau qui induit un surcoût non négligeable puisqu'une trame doit parcourir toutes les couches avant de quitter la machine source ainsi qu'à l'arrivée à la machine de destination. A l'issue de cela, nous avons caractérisé une grappe hétérogène en utilisant un modèle de graphe où les sommets sont les stations de travail caractérisées par leur puissance, leur capacité mémoire, l'impact du protocole réseau et les arcs sont les liens réseau caractérisés par leurs latences et leurs débits.

L'ordonnancement sera donc constitué du graphe représentant l'architecture et du graphe représentant l'application parallèle. Nous avons aussi modéliser les communications entre les tâches de l'application en tenant compte des éléments de coût. Ce modèle permettra d'estimer le temps de traitement d'un message transitant entre deux tâches.

Etant conscient du fait que notre problème est NP-Complet, nous nous sommes limités à donner une solution heuristique à notre problème. Elle a pour idée générale de choisir à un instant t, la tâche de coût minimal qui s'exécutera sur le processeur le plus rapide et libre de telle sorte que le temps de transfert des données nécessaires pour son exécution soit minimal.

Le dernier chapitre a constitué la partie pratique de notre travail. C'est la partie d'implémentation de notre modèle. Pour cela, nous avons dans un premier temps installer la grappe sur le plan matériel et logiciel en y intégrant tous les outils logiciels nécessaire à l'évaluation des performances du réseau et à la programmation de l'application exemple sur laquelle nous avons travaillé. Nous avons dans le même cadre dévéloppé certains programmes pour estimer les temps de latence et de surcoût induits par la pile réseau. Nous avons choisi le problème de multiplication d'une matrice par un vecteur et nous y avons appliqué un ordonnancement statique par nous-même et avons recueilli des performances.

Une fois que nous avons fait le bilan du travail qui a été fait, nous sommes passé à l'évaluation pour faire une sorte de mesure par rapport aux objectifs du départ.

Evaluation

Comme nous l'avons dit dans l'introduction générale, notre travail était de pouvoir modéliser un ordonnancement sur une grappe de calcul hétérogène après avoir décrit son modèle de coût.

Nous pensons avoir réalisé une revue de littérature consistante pour la bonne compréhension de notre problème. Cette bonne compréhension nous a permis de ressortir et illustrer correctement et essentiellement les éléments qui devaient nous être utiles tout au long de notre travail. En effet, les concepts de parallélisme et d'ordonnancement ont été bien compris ainsi que leurs constituants.

Nous avons pu élaborer un modèle d'ordonnancement qui correspond effectivement à un environnement de grappe hétérogène.

Concernant l'implémentation de notre modèle, nous nous sommes confrontés à un problème : celui de la non-existence d'un support d'exécution qui puisse permettre d'ordonnancer en tenant compte des éléments de coût tels que présentés dans notre modèle. Néanmoins, nous avons utilisé la bibliothèque de communication MPICH2 qui nous permet de faire une gestion dynamique des tâches tout au long de l'exécution de l'application. Elle nous a aussi permis de programmer une application parallèle test notamment la multiplication d'une matrice par un vecteur. Elle ne permet que de faire un ordonnancement est statique, c'est à dire le choix des processeurs est fixé au début de l'exécution du programme et reste inchangée jusqu'à la fin de l'exécution du dit programme. Ceci le rend indépendant après la première étape ( qui est celle réalisée par le programmeur ) des paramètres du modèle comme par exemple quelle tâche est minimale en terme de coût et qui nécessite ses données en temps minimal et quel processeur choisir?

Malgré ces manquements, nous avons pu mesurer les performances du réseau tels que les latences des liens, leurs débits respectifs et les surcoûts relatifs à chaque station de travail et paralléliser l'application test. Bien que l'ordonnancement a été statique nous avons pu tirer des analyses intéressantes sur les performances obtenues.

Perspectives

Afin d'atteindre nos objectifs, nous devons développé un gestionnaire de tâches qui tiendra en compte toutes les spécifications de notre modèle et de lui associer MPICH25 pour permettre la gestion dynamique des processeurs. Ensuite, il faudra le rendre générique pour certaines applications sur toutes les plateformes hétérogènes.

5ou éventuellement un autre outil

Annexe A

Annexe

1 CONFIGURATION DE NOTRE GRAPPE

1.1 Configuration logicielle

1.1.1 OAR : gestionnaire de tâches

La première chose à savoir est l'architecture OAR. L'installation du gestionnaire OAR est composé: - du server OAR qui détient <l'intelligence> de OAR.

- du serveur de base de données.

- du frontal de soumission des tâches sur lequel on va se logger pour réserver certains noeuds de calcul.

- des noeuds de calcul sur lesquels les calculs s'exécuteront.

Etant donné qu'on fait une installation sur les distributions Debian, on installera le paquet oar-server sur le serveur OAR, le paquet oar-user sur le frontal de soumission et le paquet oar-node sur les machines de calcul. On installe également mysql-server. Ajouter environment="OAR_KEY=1" au début de la clé publique dans le fichier oar/.ssh/authorized_keys.

Préréquis

Sur chaque noeud (serveur, frontal , calcul), les paquets suivants doivent être installés : sudo Perl

Perl-base

openssh (serveur et client)

Sur le serveur OAR et sur le frontal, les paquets suivants doivent être installés : Perl-Mysql Perl-DBI

MySQL

MySQL-shared

libmysql

Vers l'installation

- Ajouter un utilisateur nommé <oar> dans le groupe < <oar> sur chaque noeud.

- Créer un ensemble de clés ssh pour l'utilisateur <oar> en utilisant ssh-keygen. Pour notre cas, id_dsa.pub et id_dsa.

- Copier ces clés dans le dossier .ssh de l'utilisateur <oar>

- Ajouter le contenu de 'id_dsa.pub' au fichier oar/.ssh/authorized_keys

- Dans /.ssh/config ( créer le fichier s'il n'existe pas ), ajouter les lignes :

Host *

ForwardX11 no

StrictHostKeyChecking no

PasswordAuthentication no

AddressFamily inet

- Ajouter dans le fichier de configuration du serveur ssh

AcceptEnv OAR_CPUSET OAR_JOB_USER

PermitUserEnvironment yes

UseLogin no

AllowUsers oar

Ajouter dans le fichier ~oar/.bashrc export PATH=/usr/local/oar/oardodo:\$PATH

On n'a plus qu'à installer les paquets OAR.

Lancer le serveur OAR en utilisant l'utilisateur <oar>. Utiliser le script "/etc/init.d/oar-server" pour lancer le démon. Editer le fichier /etc/oar.conf pour faire correspondre la configuration de la grappe.

DB_TYPE=mysql

DB_HOSTNAME=localhost

DB_BASE_NAME=oar

DB_BASE_LOGIN=oar

DB_BASE_PASSWD=oar

DB_BASE_LOGIN_RO=oar_ro

SERVER_HOSTNAME=localhost

DEPLOY_HOSTNAME="127.0.0.1"

... ... ALLOWED_NETWORKS="127.0.0.1/32 0.0.0.0/0"

S'assurer que la variable d'environnement PATH contient $PREFIX/$BINDIR de notre installation. Pour notre cas, le chemin est le chemin par défaut /usr/local/bin.

Initialisation de la base de données

L'initialisation de la base de données (MySQL) est effectuée en utilisant le script oar_mysql_db_init fournit avec le paquet d'installation du serveur et stocké par défaut dans /usr/local/sbin. Etant en root, lancer ce script .

Quelques commandes

oarnodesetting

Cette commande permet de changer l'état ou la propriété d'un noeud ou de plusieurs ressources. -a : ajouter une nouvelle ressource

-s : l'état à assigner au noeud :

* "Alive" : une tâche peut être lancée sur ce noeud.

* "Absent" : L'administrateur veut enlever le noeud de la liste un moment. * "Dead" : Le noeud ne sera pas utilisé et sera supprimé.

-h : spécifier le nom du noeud.

-r : spécifier le numéro de la ressource.

Oarsub

Cette commande permet à l'utilisateur de soumettre une tâche.

Oarnodes

Cette commande affiche les informations sur les ressources de la grappe.

1.1.2 MPICH2 : bibliothèque de communications

Pré-réquis.

Pour une installation par défaut, les éléments suivants doivent être installés :

- Une distribution de la copie mpich2.tar.gz

- Le compilateur C

- Les compilateurs Fortran-77 , Fortran-90 et/ou C++ si on veut écrire nos programmes dans ces langages.

- Python 2.2 ou la dernière version pour construire le système de gestion par défaut des processus. Les étapes d'installation.

Les étapes suivantes sont celles à appliquer pour pouvoir installer MPICH2 en vue d'exécuter un programme parallèle sur plusieurs machines.

1. # tar xvzf mpich2.tar.gz

2. On choisit de créer notre répertoire d'installation avec la commande mkdir /home/user/mpich2- install. On le partage en utilisant NFS sur toutes les machines qu'on utilisera pour lancer le programme parallèle.

3. Choisir le répertoire de construction1 : mkdir /tmp/user/mpich2-1.0.8p1

4. Configurer MPICH2 en spécifiant le répertoire d'installation et exécuter le script configure dans le répertoire source :

# cd /tmp/you/mpich2-1.0.8p1

#./configure -prefix=/home/user/mpich2-install| tee configure.log

5. On construit MPICH2 # make | tee make.log

6. Installer les commandes MPICH2 # make install | tee install.log

7. Ajouter le sous répertoire bin du répertoire d'installation dans le PATH # export PATH=/home/user/mpich2-install/bin :$PATH

Tester que tout marche bien à ce niveau en faisant

# which mpd

# which mpicc

'build directory

# which mpiexec

# which mpirun

Le résultat devrait être le sous répertoire /home/user/mpich2-install/bin

8. MPICH2 contrairement à MPICH utilise un gestionnaire externe de processus pour lancer un grand nombre de tâches MPI. Il est appelé MPD qui est un anneau de daemons sur les machines où on va exécuter nos programmes MPI. Pour des raisons de sécurité, MPD cherche dans le répertoire de l'utilisateur un fichier nommé .mpd.conf contenant la ligne :

# secretword=<secretword> où secretword est une chaine de caractère qui uniquement connue par nous. Ensuite, on rend ce fichier lisible et modifiable uniquement par nous :

# cd

# touch .mpd.conf

# chmod 600 .mpd.conf

Ensuite on utilise, un éditeur pour placer une ligne comme :

secretword=chaine de caractères

Le premier contrôle consiste à faire à exécuter un programme non-MPI avec le demon MPD : # mpd&

# mpiexec -n 1 /bin/hostname

# mpdallexit

Ceci doit afficher le nom de la machine locale.

9. Etant donné que l'on veuille exécuter le programme parallèle sur plusieurs machines, on devrait lancer le daemon MPD sur chacune de ces machines. Nous devons créer un fichier nommé mpd.hosts qui contient la liste des noms complets des machines, un par ligne. Ces machines seront des cibles ssh ou rsh donc il faudrait préciser le nom complet de domaine si nécessaire. Vérifier si on peut atteindre ces machines par ssh : # ssh remotemachine date

qui doit afficher l'heure système de la machine distante

Lancer les démons sur chaque certaines (ou toutes les) machines du fichier mpd.hosts. # mpdboot -n <number to start > -f mpd.hosts

ou

# mpdboot -n <number to start>

# mpdtrace -l

<number to start > peut être inférieur à 1+ le nombre d'hôtes dans le fichier mpd.hosts mais ne peut pas être plus grand.

10. Compilation d'un programme parallèle # mpicc -o <executable> <programme.c>

11. exécution d'un programme parallèle

Après avoir lancer les daemons sur les autres machines, # mpiexec -n <nombre de processus> <executable>

1.1.3 Serveur NFS : Network file system Installation du serveur NFS

Pour installer le serveur NFS sous débian, il suffit de taper la commande :

# apt-get install nfs-kernel-server Configuration du serveur NFS.

La configuration du serveur NFS est stockée dans le fichier /etc/exports. Ce fichier de configuration

dispose d'une page de manuel :

# man exports

Ouvrir le fichier /etc/exports et ajouter la ligne pour pouvoir partager le repertoire d'installation de MPICH2 à toutes les machines

/home/user/mpich2 - install * (ro)

A chaque modification du fichier /etc/exports, il faut relancer le serveur NFS pour que les modifications soient prises en compte :

# /etc/init.d/nfs-kernel-server restart

Utilisation de NFS depuis un poste client.

Si on veut que ce répertoire soit accessible à chaque boot, il suffit de rajouter la ligne suivante dans le fichier /etc/fstab :

serveur : /home/user/mpich2 - install /home/user/mpich2 - install nfs defaults 0 0

1.1.4 Serveur NIS : Network information service

Pour installer NIS sous Débian, utiliser la commande suivante :

# apt-get install nis Configuration du serveur.

Il faut tout d'abord vérifier que le fichier /etc/hosts contient l'adresse IP et le nom complet du serveur : Il faut ensuite ajouter dans le fichier /etc/defaultdomain le nom du domaine NIS : labonis

Dans le fichier /etc/ypserv.securenets, on restreint l'utilisation du domaine NIS au domaine du réseau local.

On remplace la ligne 0.0.0.0 0.0.0.0 par : 255.255.255.0 192.168.12.0.

On modifie ensuite /etc/default/nis pour indiquer qu'il s'agit du serveur NIS :

NISSERVER=master

On relance le serveur NIS :

# /etc/init.d/nis restart

On lance ensuite la création des bases de données NIS avec la commande suivante :

# /usr/lib/yp/ypinit -m

Ceci va créer les fichiers partagés dans le répertoire /var/yp/DOMAINENIS.

Configuration du client

Il faut préciser le nom du domaine NIS fichier /etc/defaultdomain contienne le domaine NIS : labonis #vi /etc/defauldomain labonis Dans le fichier /etc/yp.conf, on indique l'adresse IP du serveur NIS : # vi /etc/yp.conf

ypserver 192.168.12.3

On démarre le client NIS :

# /etc/init.d/nis start

On vérifie que le fichier /etc/nsswitch.conf contient bien les lignes suivantes :

# cat /etc/nsswitch.conf

...

passwd : compat

group : compat

shadow : compat

...

netgroup: nis

2 Code séquentiel du produit d'une matrice par un vecteur

A la fin du fichier /etc/passwd, on rajoute la ligne suivante :

# echo 11+ : : : : : :11 > /etc/passwd

A la fin du fichier /etc/shadow, on rajoute la ligne suivante :

# echo 11+ : : : : : : : :11 > /etc/shadow

A la fin du fichier /etc/group, on rajoute la ligne suivante : # echo 11+ : : :11 > /etc/shadow

Test

Sur le serveur NIS, on rajoute un utilisateur : # adduser franklin

On met à jour la base de données NIS : # /usr/lib/yp/ypinit -m

Si tout fonctionne, on doit pouvoir se logger sur un des clients NIS avec l'utilisateur franklin.

2 Code séquentiel du produit d'une matrice par un vecteur

... ... int main()

{

double a[SIZE][SIZE],b[SIZE],c[SIZE];

struct timeval start,end;

int i,j;

initialiser(a);

for(i=0;i<SIZE;i++) b[i]=2.0;

for(i=0;i<SIZE;i++)

{c[i]=0.0;

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

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

}

....

...

Bibliographie

[1] SGI Origin 3000. URL : http :// www.SGI.com/products/servers/origin/3000/. 20

[2] A. Alexandrov, M.F. Ionescu, K.E. Schauser et C. Scheiman. LogGP : incorporating long messages into the logP model for parallel computation. Journal of parallel and distributed computing. July 1997. 42

[3] Gene M. Amdahl. Validity of the single processor approach to achieving large scale computing capabilities.afips 1967 spring joint computer conference. volume 30, page 483-485, Apr 1967. 25

[4] Henri Casanova, Frédéric Desprez et Frédéric Suter. From heterogeneous task scheduling to heterogeneous mixed parallel scheduling. In Marco Danelutto, Domenico Laforenza, et Marco Vanneschi, editors, Proceedings of the 10th International Euro-Par Conference (Euro-Par'04), volume 3149 of LNCS, page 230-237, Pisa, Italy, August/September 2004. Springer. 14

[5] Gerson G.H Cavalheiro. Thèse : ATHAPASCAN-1 : Interface générique pour l'ordonnancement dans un environnement d'exécution parallèle. 22 Novembre 1999. 28

[6] Philippe Chretienne. Task Scheduling Over Distributed Memory Machines In Michel Cosnard Patrice Quinton Michel Raynal et Yves Robert, editors, Parallel and distributed Algorithms. 1988. 53

[7] Y. Colin et P. Chretienne. CPM scheduling with small interprocessor communication delays. operations research. 1991. 41

[8] Condor. URL : http :// www.cs.wisc.edu/condor/. 15

[9] D.E. Culler, R.M. Karp, D. Patterson, A. Sahay, E.E. Santos, K.E. Schauser, R. Subramonian et T. von Eicken. LogP : A practical model of parallel computation. Communications of the ACM. November 1996. 41

[10] V.-D. Cung, P. Fraigniaud, T. Gautier et D. Trystram. De l'algorithme au support. In D. Barth, J. Chassin de Kergommeaux, J.-L. Roch, and J. Roman, editors, ICaRE'97 : Conception et mise en xuvre d'applications parallèles irrégulières de grande taille. Aussois, France, December 1997. CNRS. 29

[11] J. Eisenbiegler, W. Lowe et A. Wehrenpfennig. On the optimization by redundancy using an extended logP model. In international conference advances in parallel and distributed computing. 1997. 42

[12] M.J Flynn. Reaction of the absorber as the mechanism of radiative damping. volume 54, pages 1901-1909, Decembre 1966. 8

[13] Ian Foster et Carl Kesselman. The grid : Blueprint for a new computing infrastructure. Morgan Kaufmann, San Francisco, 1999. 14

[14] hesham el rewimi et mostafa abd-el barr. Advanced Computer Architecture and Parallel Processing. A John Wiley and Sons, INC PUBLICATION, 2005. 8, 22, 23

[15] J.M.D. Hill, W.F. McColl et D.B. Skillircon. Questions and answers about BSP. Technical report PRG-TR-15-96, Oxford University Computing Laboratory. November 1996. 42

[16] InfiniBand. URL : http ://www.OpenPBS.org/. 21

[17] R. M. Karp et V. Ramachandran. Parallel algorithms for sharedmemory machines. in j. van leeuwen, editor, handbook of theoretical computer science. A : Algorithms and Complexity : 870-941, 1990. 36

[18] W.F. McColl. Scalable computing.In J. van Leeuwen, editor, Computer Science Today : Recent Trends and Developments Springer-Verlag, 1995. 42, 43

[19] Guillaume MERCIER. Communications à hautes performances portables en environnements hiérarchiques, hétérogènes et dynamiques. decembre 2004. 17

[20] technologie réseau Myrinet Myricom. URL : http ://www.myri.com/. 21

[21] Nanette J. B ODEN Danny C OHEN, Robert E. F ELDERMAN, Alan E. K ULAWIK, Charles L.S EITZ, Jakov N. S EIZOVIC et Wen-King S U. Myrinet : A Gigabit-per-Second Local Area Network. IEEE Micro, volume 15., février 1995. 21

[22] C.H. Papadimitriou et J. Ullman. A communication time tradeoff. SIAM journal on computing. pages 16(4) :639-646, 1987. 38

[23] C.H. Papadimitriou et M. Yannakakis. Towards an architectureindependent analysis of parallel algorithms. siam journal on computing. pages 19(2) : 322-328, April 1990. 39

[24] Quadrics. URL : http ://www.Quadrics.com/. 21

[25] Andrei Radulescu, Cristina Nicolescu, Arjan J. C. van Gemund et Pieter Jonker. CPR. Mixed task and data parallel scheduling for distributed systems. In Proceedings of the 15th International Parallel and Distributed Processing Symposium (IPDPS'01). IEEE Computer Society, 2001. 13

[26] Andrei Radulescu et Arjan J. C. van Gemund. A low-cost approach towards mixed task and data parallel scheduling. In Proceedings of the 15th International Conference on Parallel Processing (ICPP'01), page 69-76. IEEE Computer Society, 2001. 13

[27] Shankar Ramaswamy, Sachin Sapatnekar et Prithviraj Banerjee. A Framework for Exploiting Task and Data Parallelism on Distributed Memory Multicomputers. IEEE Transactions on Parallel and Distributed Systems. IEEE Computer Society, Nov 1997. 13

[28] V.J. Rayward-Smith. UET scheduling with unit interprocessor communication delays. Discrete Applied Mathematics. 1987. 39

[29] MPI Forum ( Standards; archives; etc.). URL : http ://www.MPI-Forum.org/. 7

[30] L.G. Valiant. A bridging model for parallel computation. communications of the ACM. pages 33(8) :103-111 August 1990. 42, 43

[31] Cray XT3. URL : http :// www.Cray.com/products/xt3/index.html. 21

[32] YAMPII. URL : http ://now.cs.berkeley.edu/. 16






Bitcoin is a swarm of cyber hornets serving the goddess of wisdom, feeding on the fire of truth, exponentially growing ever smarter, faster, and stronger behind a wall of encrypted energy








"Il faut répondre au mal par la rectitude, au bien par le bien."   Confucius