• Aucun résultat trouvé

4.5 Langages de relations

4.5.4 Mise en œuvre et génération de composants glus

La mise en œuvre de greffons de relations est décrit par une classe et un fichier de template dans le compilateur associé à un identifiant (nom du langage de relations). Pour chaque type de métatâche (issu des instances d’un assemblage), le compila-teur extrait le nom du langage de relations utilisé. En fonction de l’identifiant, il instancie la classe associée à l’identifiant et lui fournit des informations issues de la phase d’analyse sémantique pour le type de métatâche ciblée. Cela veut dire que les instances de la classe ont accès à l’expression de relation ainsi qu’aux ports de la métatâche (attributs, types de partitionnement, etc.). Le rôle de la classe est d’ana-lyser l’expression afin de produire une structure de données associée au template dans le but de générer la partie fonctionnelle (soumission de tâches et génération des interfaces spécifiques) du code d’un composant glu associé à une métatâche. Le code généré par les greffons est inclus dans un code définissant un composant. Ce dernier contient une partie du code non fonctionnel des composants glus (p. ex. structure du composant) générée par le compilateur à partir un template commun à tous les greffons. Un exemple de composant glu généré est fourni à l’annexeB.7 à la page176.

4.6 Conclusion

Dans ce chapitre, nous avons analysé la façon dont fonctionne Halley, une mise en œuvre de Comet. À cette fin, nous avons évoqué les objectifs qu’il remplit et présenté son fonctionnement. Puis, nous avons décrit comment fonctionne la com-pilation source à source, basée sur des méthodes issues de l’ingénierie dirigée par les modèles et rendue extensible par un système de greffons. Ensuite, nous avons décrit comment chaque sorte de greffon fonctionne et quel est le rôle de chaque sorte : des greffons de données, aux greffons de données partitionnés, en passant par les greffons de repartitionnement et les greffons de relations.

Chapitre 5

Évaluation sur des cas d’utilisation

syn-thétiques

Contents

4.1 Fonctionnement . . . 70 4.1.1 Objectifs . . . 70 4.1.2 Fonctionnement général . . . 71 4.2 Compilation source à source . . . 72 4.2.1 Ingénierie dirigée par les modèles . . . 72 4.2.2 Métamodèle source et métamodèle de destination . . . 73 4.2.3 Transformation de modèles . . . 74 4.3 Support des types de données . . . 82 4.3.1 Interfaces des greffons . . . 83 4.3.2 Enregistrement de greffons et paramétrage . . . 84 4.4 Support des données partitionnées et repartitionnement 85 4.4.1 Interfaces des greffons . . . 86 4.4.2 Mécanismes de cohérence . . . 90 4.4.3 Enregistrement des greffons et paramétrage . . . 92 4.5 Langages de relations . . . 92 4.5.1 Fonctionnement général et intégration . . . 93 4.5.2 Langages de relations . . . 94 4.5.3 Interfaces . . . 94 4.5.4 Mise en œuvre et génération de composants glus . . . 97 4.6 Conclusion. . . 97

Afin d’évaluer simplement Comet et plus précisément sa mise en œuvre Hal-ley, il est essentiel de disposer d’un jeu de cas d’utilisation issus de patrons ré-currents dans les applications HPC telles que Gysela et permettant d’effectuer des mesures de performance et relative à la maintenabilité logicielle : benchmark. Idéa-lement, il serait bénéfique d’utiliser un benchmark commun existant afin de pouvoir

comparer plus aisément les approches. Certains benchmarks, tels que le NAS paral-lel benchmark [11] (NPB), LINPACK [41], HPC Challenge [81] et HPC Conjugate Gradients [42] sont des références dans la communauté HPC. Cependant, ils ne per-mettent pas d’évaluer les propriétés relatives à la conception et la maintenance des applications (p. ex. bénéfices des modèles à composants, notamment pour compo-sition des codes parallèle), car chaque expérience des benchmarks est généralement constituée d’un unique noyau de calcul formant un code concis, atomique et cohé-rent. L’évaluation du modèle de composants, Comet et plus précisément sa mise en œuvre, Halley est donc ardue étant donné qu’il n’existe pas de benchmark permettant d’étudier les propriétés des modèles à composants HPC.

Pour résoudre ce problème, ce chapitre réalise une évaluation à partir d’un bench-mark synthétique “sur-mesure” dont le contenu est inspiré des applications HPC telles que Gysela ainsi que de benchmarks comme le NPB. Ce chapitre se concentre plus particulièrement sur l’analyse des performances de la composition de codes pa-rallèle utilisant le modèle Comet, ainsi qu’un aperçu des avantages et inconvénients d’une telle méthode sur la conception d’applications HPC. Ce chapitre expose et ana-lyse des comportements complexes qui se manifestent dans des expériences simples. Il est complété par le chapitre 6 qui analyse un cas d’étude réaliste tirée de l’ap-plication de production Gysela. Ce dernier fournit une analyse plus développée des considérations relatives à la conception d’application à plus large échelle.

Ce chapitre présente, tout d’abord, les cas d’utilisation utilisés pour évaluation. Ensuite, il traite de l’impact de Comet sur la séparation des préoccupations. Enfin, ce chapitre évalue les performances des cas d’utilisation en comparant des versions utilisant le modèle Comet (plus précisément la mise en œuvre Halley) avec des versions utilisant directement OpenMP à travers des codes écrits manuellement (dé-veloppés spécifiquement pour l’évaluation présente dans ce manuscrit).

5.1 Cas d’utilisation

Aperçu des cas d’utilisation Cette section présente tout d’abord trois cas d’uti-lisation choisis dans ce chapitre pour évaluer Halley : EP (pour “embarrassingly parallel”), ST (pour “stencil”), et TRANSP (pour “transpose-based FFT”). Ils re-présentent des cas de patrons récurrents pouvant être trouvés dans les applications HPC par exemple disponibles dans le NPB (pour EP et TRANSP) ainsi que dans Gysela (pour EP, ST et TRANSP).

EP est un cas d’utilisation effectuant des opérations indépendantes exécutables massivement en parallèle (embarrassingly parallel). Les opérations appliquées traitent des blocs d’un tableau bidimensionnel (opération mémoire sur-place) et sont limitées par la mémoire (une seule opération flottante est appliquée sur chaque case).

ST est un cas d’utilisation visant à résoudre l’équation de la chaleur par la méthode de Jacobi. C’est un stencil 4-points appliqué sur un tableau bidimensionnel, majoritairement limité par la mémoire. Tout comme pour EP, le tableau est découpé en blocs bidimensionnels. Chaque tâche de ce cas lit cinq blocs d’un buffer et écrit dans un bloc d’un autre buffer.

5.1. CAS D’UTILISATION 101 même b uff er d e d o n n ées même b uff er d e d o n n ées

repartition repartition repartition

même b uff er d e d o n n ées EP ST EP-EP ST-ST TRANSP Légende Tâche Buffer partitionné Dépendance Représentations d'un même buffer

Figure5.1 – Structure des graphes de tâches de chacun des cinq cas d’utilisation. De gauche à droite et de haut en bas : EP, ST, EP-EP, ST-ST, TRANSP.

TRANSP est un cas d’utilisation qui consiste en deux phases de calculs intensifs ligne par ligne d’un tableau bidimensionnel, entrelacées par des transpositions du tableau. L’ensemble des calculs est effectué sur-place en mémoire. Ce patron est assez fréquemment utilisé dans les applications HPC. Par exemple, les algorithmes de transformé de Fourrier rapide (FFT) ou encore par des méthodes d’interpolation à base de splines ont souvent recours à cette méthode.

Deux autres cas évaluant la composition et l’intérêt du repartitionnement s’ajoutent aux trois premiers : EP-EP et ST-ST. EP-EP et ST-ST réalisent chacun une exé-cution consécutive de deux cas EP (et respectivement ST) interdépendants.

La figure 5.1 présente la structure des graphes de tâches des cinq cas d’utilisa-tion. Les opérations de repartitionnement sont affichées explicitement. Tous ces cas d’utilisation utilisent un partitionnement en blocs réguliers (de taille uniforme). Variantes comparées Pour chaque cas d’utilisation, une version de référence est écrite manuellement en OpenMP sans aucun code généré. Elle produit un graphe avec le même nombre de tâches et les mêmes dépendances qu’une version utilisant Halley. Le but est d’évaluer le surcoût engendré par Halley et d’examiner les bénéfices apportés par Comet lors de la conception des cas d’utilisation.

Assemblages des cas d’utilisation Chaque cas d’utilisation est associé à un as-semblage possédant une unique section dataflow. Une exécution d’un cas d’utilisation est constituée de 20 exécutions de la section dataflow (itérations).

L’assemblage Halley du cas d’utilisation EP est composé de deux composants (l’un dirige l’assemblage et l’autre fournit une mise en œuvre pour la métatâche de

<metatask id="EpMt">

<parameter id="dWidth" type="uint64"/> <parameter id="dHeight" type="uint64"/> <parameter id="bWidth" type="uint64"/> <parameter id="bHeight" type="uint64"/>

<inPort id="inout" type="BlockedArray2D" dataBufferSetter="fData"

dataPartitionSetter="fPart"/> <relation language="identity"/>

<setting language="python3">

def fData(mt):

return dict(width=mt.dWidth, height=mt.dHeight, elemSize=8) def fPart(mt):

return dict(blockWidth=mt.bWidth, blockHeight=mt.bHeight)

</setting> </metatask>

Figure 5.2 – Type de métatâche utilisé pour le cas d’utilisation EP.

la section) et d’une section contenant une unique instance de métatâche. Le code complet de l’assemblage est fourni en annexeB.8(page178). Le type de la métatâche de ce cas d’utilisation est décrit à la figure 5.2. Ce type de métatâche dispose d’un unique port d’entrée-sortie traitant des tableaux bidimensionnels partitionnés en blocs réguliers et a recours au langage de relations identité. Chaque tâche opère donc sur un unique fragment et il y a autant de tâches soumises par une métatâche que de blocs dans la partition.

L’assemblage Halley du cas d’utilisation ST dispose d’une structure identique à EP, mais les types des composants et des métatâches sont différents (ainsi que les connexions de données). Le code complet de l’assemblage est fourni en annexe B.9 (page179). La figure4.18du chapitre4(page94) fournit une description du type des métatâches du cas d’utilisation ST. Ces métatâches possèdent un port d’entrée et un port de sortie distincts, tous deux acceptent des buffers de données bidimensionnels partitionnés en blocs réguliers et ont recours au langage de relations align. Chaque tâche lit le voisinage d’un fragment (cinq fragments) à la position pi, jq issu du port in et écrit dans le fragment issu du port out qui cette même position pi, jq, avec i et j des variables implicites itérant l’espace des fragments. Il y a donc autant de tâches soumises par une métatâche que de fragments du partitionnement du port out (identique au nombre de fragments issu du port in).

Les assemblages Halley respectifs des cas d’utilisation EP-EP et ST-ST sont similaires aux cas EP et ST : dans les deux cas, une nouvelle instance de métatâche est ajoutée et un buffer temporaire est ajouté afin d’assembler les instances de métatâches. Dans le cas d’utilisation ST, un composant dirigeant l’assemblage est remplacé par un autre, car la composition de deux stencils réalisée utilise un buffer permanent et un buffer temporaire plutôt que deux buffers permanents (les interfaces du composant sont différentes et un échange de buffers n’est plus requis dans sa mise