• Aucun résultat trouvé

3.3 Discussion sur le modèle de programmation

3.3.2 Structuration des données du programme

La granularité des objets partagés influence directement le degré de parallélisme des tâches qui seront créées. Par exemple, invoquer plusieurs tâches modifiant des parties dis-tinctes d’un même objet partagé ne générera pas de parallélisme supplémentaire puisque, dans le modèle de programmation, les contraintes d’accès sur un objet partagé s’ap-pliquent à l’ensemble des données de cet objet. Le système d’exécution va alors considérer que chacune de ces tâches accède à l’ensemble de l’objet partagé, il va donc les exécuter les unes après les autres. De plus, si ces tâches sont exécutées sur différens processeurs d’une machine à mémoire distribuée, des copies inutiles de l’objet seront réalisées entre les différents nœuds.

2. Plus exactement seule la continuation d’une tâche située après un mot clefsyncpeut se synchroniser sur la terminaison d’autres tâches.

Le programmeur doit également éviter pour la même raison de regrouper sur un même objet partagé des données qui seront éventuellement accédées différemment par une tâche. Par exemple, considérons une tâche accédant un objet partagé, contenant deux donnéesA

etB respectivement lue et modifiée par cette tâche. L’objet contenant Aet B doit donc être pris en paramètre par la tâche avec un droit d’accès en lecture-écriture même si A

n’est accédé qu’en lecture.

Cette structuration des données suivant la granularité choisie pour exprimer le paral-lélisme est peut être ce qui est le plus contraignant lors de l’écriture d’un programme Athapascan-1. Cependant cette structuration des données d’un programme en vue de son exécution sur une machine à mémoire distribuée est généralement indispensable sur la plupart des modèles de programmations offrant une mémoire partagée distribuée. La so-lution consistant à utiliser une mémoire virtuellement partagée du type de celle fournie par TreadMarks [3], et à synchroniser les tâches explicitement, pourrait être considérée comme une solution permettant d’éviter cette structuration des données suivant la gra-nularité choisie pour exprimer le parallélisme. Mais en pratique, cette simulation d’un espace d’adressage unique est réalisée au niveau de la page du système d’exploitation. Le programmeur doit alors également structurer ces données pour les aligner sur les pages du système s’il veut obtenir de bonnes performances. Il doit éviter par exemple de placer sur une même page deux données qui seront accédées en parallèle par deux tâches dif-férentes3. De plus le surcoût induit par la simulation d’un espace d’adressage unique est généralement important, comparé à celui induit par la gestion d’une mémoire partagée au niveau objet [9]. Ainsi, même sur une mémoire virtuellement partagée, les données doivent être structurées en fonction de la granularité du parallélisme si les performances sont recherchées.

Par contre, spécifier le type des accès qui seront réalisés sur les objets partagés n’est pas un problème. Beaucoup de langages de programmation supportent des notions simi-laires. Par exemple, en C ou C++ le mot clé const est utilisé devant un nom de type pour préciser que la variable ou l’objet est constant donc qu’il ne pourra être modifié. En ADA et en Fortran 90 les mots clefs inet outpermettent d’indiquer lors de la déclara-tion des paramètres formels d’une procédure, le type d’accès pouvant être réalisé sur ces paramètres ; lecture pour un paramètre passée en mode in, affectation pour un paramètre passée en mode outet lecture-écriture pour un paramètre passée en mode in out.

3.4 Conclusion

Nous avons présenté dans ce chapitre le modèle de programmation parallèle d’Atha-pascan-1. Ce modèle permet une programmation parallèle simple et de haut niveau. Ceci 3. Des protocoles d’écritures multiples sur une même page par différents processeurs ont cependant été développés et permettent de résoudre en partie ce problème [3].

Conclusion 3.4 est obtenu par trois mécanismes offerts par le modèle :

– Une mémoire partagée distribuée permet de libérer le programmeur de la distribu-tion et de la communicadistribu-tion des données.

– La décomposition de l’exécution sous la forme de tâches conduit à une abstraction du nombre de processeurs et libère ainsi le programmeur de l’ordonnancement et de la régulation de charge. Seul le choix de la granularité des tâches et donc du degré de parallélisme de l’application, reste à la charge du programmeur.

– Les synchronisations entre les tâches sont implicitement définies à partir de la sé-mantique du modèle de programmation qui est une sésé-mantique « séquentielle » et donc naturelle pour le programmeur.

Par ailleurs, dans le but de permettre une mise en œuvre efficace de ce modèle de programmation, plusieurs choix ont été pris :

– Les accès à la mémoire partagée distribuée se font au niveau des objets et non au niveau du mot mémoire élémentaire.

– Chaque tâche déclare dans son prototype les accès qu’elle (et sa descendance éven-tuelle) pourra réaliser sur les objets en mémoire partagée. Ainsi le système connaît l’ensemble des effets de bord pouvant être réalisés par les tâches sur les objets par-tagés. Il peut alors facilement analyser les dépendances de données entre les tâches et ainsi définir les synchronisations nécessaires au respect de la sémantique séquen-tielle.

– Aucune dépendance de données entre une tâche mère et une tâche fille n’est au-torisée. Ainsi une tâche peut toujours s’exécuter sans synchronisation. Il est alors possible de mettre en œuvre des mécanismes d’ordonnancement et de régulation de charge prouvé théoriquement efficace.

Ces choix seront justifiés plus en détail dans la suite de cette thèse et plus particulièrement dans les deux chapitres suivants dans lesquels un modèle de coût de l’exécution d’un programme Athapascan-1 sera proposé.

4

Modèle d’exécution d’un

programme Athapascan-1

4.1 Introduction

Le modèle de programmation Athapascan-1 introduit dans le chapitre précédent per-met d’exprimer le parallélisme indépendemment de l’architecture. L’exécution d’un pro-gramme repose alors sur un système d’exécution qui contrôle la répartition (ou plutôt le repliement) d’un programme sur l’architecture cible. Ce chapitre est consacré à la présen-tation de ce système, dont comme nous le verrons, l’implémenprésen-tation dépend de l’archi-tecture cible.

Le rôle du système d’exécution associé à Athapascan-1 est double :

– D’une part, détecter les synchronisations qui sont implicites dans le langage Atha-pascan-1. Dans ce chapitre nous proposerons une méthode basée sur la construction d’un graphe de flot de données. Ce graphe, construit au cours de l’exécution, repré-sente à tout instant les dépendances de données entre les différentes tâches déjà créées mais non encore exécutées.

– D’autre part, l’ordonnancement du programme, à savoir le placement et l’entrela-cement des tâches de calculs et la localisation des objets partagés. Le graphe de flot de données construit en cours d’exécution fournit alors un bon support pour le calcul de cet ordonnancement. Par exemple, une grande partie des algorithmes d’ordonnancement statique utilisent ce type de graphe.

Nous montrerons alors dans ce chapitre trois modèles d’exécution d’Athapascan-1, dans lesquels la politique d’ordonnancement utilisée est clairement séparée des différents

mécanismes nécessaires à l’exécution (i.e. interprétation du flot de données, gestion des objets distribués, ...). Les différents algorithmes d’ordonnancement pouvant être utilisés dans ces modèles d’exécution seront quant à eux étudiés dans le chapitre 5.

La structure du chapitre est la suivante. Dans une première partie, nous modélisons l’exécution d’un programme Athapascan-1 par un graphe de flot de données. Nous mon-trons ensuite comment ce graphe de flot de données est implicitement construit et utilisé pendant l’exécution d’un programme Athapascan-1. Finalement, nous introduisons trois modèles d’exécution d’un programme Athapascan-1, qui tirent plus ou moins parti de la connaissance de ce graphe.