440 likes | 519 Views
Optimisation dynamique logicielle des accès aux données par prédiction de Markov sur les pas en mémoire et préchargement. Implantation dans le compilateur Open64. Jean Christophe Beyler ICPS/LSIIT Université de Louis Pasteur de Strasbourg 16/12/2004. Plan. Présentation Système dynamique
E N D
Optimisation dynamique logicielle des accèsaux données par prédiction de Markov sur les pas en mémoire et préchargement. Implantation dans le compilateur Open64. Jean Christophe Beyler ICPS/LSIIT Université de Louis Pasteur de Strasbourg 16/12/2004
Plan • Présentation • Système dynamique • Modèle Markovien • Exemple d’implémentation • Création du modèle • Résultats expérimentaux • Open64 • Conclusion
Présentation • Optimisation statique: • Lors de la compilation • Limitations des optimisations statiques • Paramètres inconnus lors de la compilation • Les défauts de cache • Techniques de préchargement simples
Présentation • Utilisation d’un système dynamique: • Exécution d’optimisation pendant l’exécution • Solution matérielle : • Permet de repérer les défauts de cache • Plus rapide mais il y a un coût en matériel • Solution logicielle : • Portable • Modelable • Plus lent
Historique de systèmes logiciels • Dynamo (Hewlett Packard) en 2000 (Duesterwald etal.): • Optimise des portions du code • Transparent • Deli (Hewlett Packard) en 2002 (Duesterwald etal.): • Optimise des portions du code • 2 versions: Transparente et API • Un autre optimiseur en 2002 (Chilimbi et Hirzel) : • Optimisation des accès mémoire • Autonome et puissant mais que sous Windows • Adore en 2003(Lu etal.): • Optimisation des accès mémoire : insertions de lfetch (Itanium) • Limité au cas des boucles
Modèle Markovien • Analyse statistique d’une suite S d’éléments (des accès mémoire dans notre cas) • Mise sous forme de couples (X,Y) où: • X et Y sont des éléments de la suite • X précède Y • Mais aussi (S’,Y) où: • S’ est une sous suite de S • Tous les éléments de S’ précèdent Y
Système dynamique logiciel • Propriétés générales : • S’exécute en même temps que le programme cible • Portable • Relativement léger • Facile à utiliser • Propriétés spécifiques à ESODYP (An Entirely Software and Dynamic Data Prefetcher) : • Modélise les comportements mémoires • En étudiant les sauts mémoires effectués • Précharge les données dans le cache
Déroulement de notre modèle • Le programme cible envoie les accès mémoire au modèle • Deux possibilités : • Il modélise le comportement des accès mémoires reçus (phase de construction) • Il exploite les données afin de prédire et précharger les futurs accès (phase de prédiction)
Structures de données • Le programme peut posséder plusieurs accès coûteux • Chaque séquence est probablement unique: • Paramètres différents utilisés par le modèle • Réactions différentes du modèle par rapport aux séquences • Chaque séquence aura une structure de données associée
Exemple concret • Treeadd du banc d’essai Olden • Création et parcours d’un arbre binaire par la gauche • Modification du code • Plus de 90% du temps se déroule dans la fonction Treeadd • Dans cet exemple, un accès nous intéresse donc une seule structure est nécessaire
Initialisation • Durée de construction • Profondeur • Distance • Erreurs maximum
Code de la fonction Treeadd int TreeAdd (t) register tree_t *t; { ... tleft = t->left; t : donnée intéressante à leftval = TreeAdd(tleft); précharger tright = t->right; rightval = TreeAdd(tright); value = t->val; return leftval + rightval + value; }
Code de la fonction Treeadd int TreeAdd (t) register tree_t *t; m1: structure de données { associée ... #ifdef __MARKOV__ fct : pointeur de fonction, m1->fct(m1,t); permet de passer l’information #endif tleft = t->left; t : donnée intéressante à leftval = TreeAdd(tleft); précharger tright = t->right; rightval = TreeAdd(tright); value = t->val; return leftval + rightval + value; }
int TreeAdd (t) register tree_t *t; { ... #ifdef __MARKOV__ m1->fct(m1,t); #endif tleft = t->left; leftval = TreeAdd(tleft); tright = t->right; rightval = TreeAdd(tright); value = t->val; return leftval + rightval + value; } Pointeur de fonction permet de : passer de la phase de construction à la phase de prédiction Paramètres Structure m1 permettant de modifier fct et les autres données La donnée qui est un élément de la séquence à étudier Chaque séquence possède sa propre structure Paramètres différents Phase différente La fonction fct
Remarques • La plupart des optimiseurs : • S’intéressent aux adresses accédées : • Un programme accédant trop d’adresses distinctes n’est pas parfaitement modélisable • Notre modèle : • S’intéresse aux sauts effectués : • Permet de simplifier le modèle dans le cas de programmes ayant un comportement mémoire « suffisamment constant » • Préchargement de plusieurs sauts en avance : • Permettre au chargement de se finir • Danger d’écrasement de données
Type de modèle • Suite récupérée : 12 16 2 32 2 16 2 32 • Modèle statistique mais sous forme: • De tableau? • De graphe?
Un tableau 12 16 2 32 2 16 2 32 • Profondeur : 1 • Incertitude sur une des prédictions
Un tableau 12 16 2 32 2 16 2 32 • Profondeur : 2 • Prédiction plus fine • Inconvénients avec des tableaux : • Problèmes d’allocation • Temps de recherche d’une suite
Création du graphe 12 16 2 32 2 16 2 32 1
2 2 1 1 1 2 2 Création du graphe 12 16 2 32 2 16 2 32 1
2 2 16 1 1 2 2 1 1 16 16 Création du graphe 12 16 2 32 2 16 2 32 1 16 1 1
2 2 16 16 1 1 1 2 2 1 16 16 2 2 1 1 Création du graphe 12 16 2 32 2 16 2 32 1 1 1 1
2 2 16 16 32 32 1 1 32 32 1 1 1 1 1 2 2 1 16 16 2 2 1 1 Création du graphe 12 16 2 32 2 16 2 32 1 1 1 1
2 2 16 32 32 2 1 1 32 32 1 1 1 1 1 2 2 16 2 2 2 2 1 1 1 Création du graphe 12 16 2 32 2 16 2 32 1 1 1 1 1 1
16 16 32 32 2 2 1 1 32 32 2 1 1 1 1 2 16 16 2 2 2 1 1 1 1 Création du graphe 12 16 2 32 2 16 2 32 1 1 1 1 1 1
32 2 16 32 2 2 2 16 16 2 2 2 1 1 1 Création du graphe 12 16 2 32 2 16 2 32 1 2 16 1 1 2 1 1 1 1 1 2 1 1 1
2 32 2 32 32 2 2 2 16 2 2 2 1 Création du graphe 12 16 2 32 2 16 2 32 1 2 16 32 1 1 2 2 1 1 1 2 2 1
Début des prédictions • Temps de construction assez lourd • Arrêt de la construction • Utilisation du modèle tant qu’il est efficace • Représente bien le comportement • Un programme possède plusieurs phases : • Graphe spécifique à la phase • Reconstruction lorsque le nombre d’erreurs consécutives est trop importante • Equilibre entre trop de constructions et trop d’erreurs
2 32 32 2 2 2 16 2 2 2 1 1 Phase de prédiction 2 16 1 48 2 16 2 1 16 32 32 2 1 2 2 2 1 2 1 2 2 1 Erreurs consécutives: 0
2 32 32 2 2 16 2 2 16 2 1 1 Phase de prédiction 2 16 1 48 2 16 2 1 16 32 32 1 2 2 2 2 2 1 2 2 2 2 Erreurs consécutives: 0
1 2 32 2 2 2 2 16 1 2 Phase de prédiction 2 16 1 48 2 16 2 1 16 32 32 1 2 2 2 1 16 2 2 2 Erreurs consécutives: 0 1
1 2 32 2 2 2 2 2 1 1 2 Phase de prédiction 2 16 1 48 2 16 2 1 16 32 32 1 2 2 2 1 16 2 2 2 Erreurs consécutives: 2 1
2 2 32 2 2 2 2 1 2 Phase de prédiction 2 16 1 48 2 16 2 1 16 32 32 1 2 2 2 1 16 2 2 2 3 Erreurs consécutives: 2
2 2 2 32 2 2 2 2 2 2 16 1 2 Phase de prédiction 2 16 1 48 2 16 1 16 32 32 1 2 2 2 1 16 2 2 2 Erreurs consécutives: 3 0
Résultats sur Itanium-2 • treeadd : distance est importante • ks : profondeur 2 est meilleure • equake : distance trop grande peut faire baisser l’accélération • mcf : meilleure optimisation
Résultats sur AMD Athlon XP 2600+ • Raisons pour les différences: • prefetch: instruction différente • Différentes taille de lignes de cache: • Itanium-2 : L2-D 128 octets • Athlon XP 2600+: L2-D 64 octets • Vitesse de programme
Remarques sur le modéle • Le modèle est: • Portable • Réaliste • Pas encore autonome et transparent • Quatre critères à choisir: • Durée de construction • Profondeur • Distance de préchargements • Erreurs maximum avant reconstruction • Il faut trouver les accès à la main
Transparence • Utilisation du compilateur Open64 • Compilateur Open-Source pour l’Itanium d’Intel • Compile le C, C++ et le Fortran 90/95 • Permet d’implémenter un profileur • Première exécution pour déterminer les accès intéressants • Aide à choisir les accès intéressants • Laisse juste la distance de préchargement à déterminer
Open64 driver (sgicc/sgif90/sgiCC) front end + IPA (gfec/gfecc/mfef90) back end (be, as) linker (ld) WHIRL (.B/.I) obj (.o) Src (.c/.C/.f) a.out/.so Data Path Fork and Exec WHIRL: Winning Hierarchical Intermediate Representation Language
Open64 -O3 -IPA LNO Local IPA Main IPA Lower to High W. .B Inliner gfec .I lower I/O gfecc (only for f90) .w2c.c WHIRL C f90 .w2c.h .w2f.f WHIRL fortran -O0 Take either path Lower all CG Very high WHIRL -phase: w=off High WHIRL Main opt Lower Mid W -O2/O3 Mid WHIRL Low WHIRL
La modification de Open64 • Modification de l’arbre syntaxique • Lors d’un chargement • Appel d’une fonction externe pour étudier le comportement mémoire • Utilisant plusieurs paramètres différents • Modification du code source • Ajout de deux appels: create_Markov_manager, stop_Markov_manager • Permet d’initialiser la mémoire • Permet d’afficher les résultats
Instructions précédentes Prochaines instructions Load A Registre R = A m->fct(m,R) Load R Arbre syntaxique • Avantage de Open64: • Simple à mettre en œuvre • API riche • Remarques: • Version simplifiée • Cas du if, boucle…
Et ensuite… • On classe les résultats, conservant ceux ayant les meilleurs résultats. • Problème de: • Classement • Sélection • Ces derniers seront insérés par le compilateur pour permettre d’obtenir des accélérations.
Conclusions • L’utilisation de Open64 permet • De choisir les accès potentiels et de déterminer la profondeur de création, de construction… • Donc rendre transparent le modèle • Par contre, la distance de préchargement vis-à-vis du temps est difficilement discernable. • Perspectives: • Rendre le modèle plus efficace • Rendre le modèle de sélection plus intelligent