• Aucun résultat trouvé

Réglages du compilateur dynamique

7.2 Techniques d'optimisations dynamiques

7.2.2 Réglages du compilateur dynamique

Certaines techniques ne permettent pas d'avoir un contrôle direct sur le code généré mais un contrôle sur le comportement du compilateur dynamique.

Le contrôle du compilateur dynamique a pour objectif d'améliorer son ecacité (cf. Section 2.3.2.1 Chap. 2) en dénissant statiquement des directives par l'intermédiaire de chier de conguration ou bien d'annotations dans le code applicatif. On distingue deux types de directives au compilateur dynamique :

1. Les directives globales qui aectent la politique de compilation dynamique (cf. Section 7.2.2.1) ;

2. Les directives localisées qui aectent des sites applicatifs sélectionnées (cf. Section 7.2.2.2).

7.2.2.1 Directives globales

Politique de compilation Dans [74], Hoste et Al. ont souligné l'importance des réglages du JIT pour les performances et ont proposé un outil pour la recherche automatique d'optimums. Les expérimentations menées sont spéciques à la machine virtuelle Jikes RVM12.

L'étude distingue deux paramètres à déterminer pour une méthode donnée.

Les heuristiques de compilation qui déterminent quelle méthode compilée, quand et avec quelle niveau de compilation. Jikes RVM possède plus précisément trois niveaux de compilation aecté selon la criticité de la méthode à compiler ;

12Jikes RVM (pour Research Virtual Machine) [173] est un environnement d'exécution Java, libre et open-source destiné à la recherche. Ses particularités sont d'être méta-circulaire, à savoir écrit en Java, et, contrairement à d'autres environnements méta-circulaires, de ne pas utiliser d'interpréteur mais uniquement des compilateurs [7]

Les plans d'optimisations correspondant à chaque niveau de compilation. Un plan de compilation est plus précisément déni par un ensemble d'options, 33 options boo-léennes permettant d'activer ou non une optimisation particulière et 10 paramètres à xer.

L'outil proposé permet d'identier dans un premier temps les plans Pareto-optimaux (i.e. tels qu'il n'en existe pas d'autres qui fassent mieux en termes de durée de compilation et de qualité du code). Dans un second temps il aecte ces plans aux diérents niveaux de compilation puis recherche les heuristiques de compilation optimales pour une aectation donnée. Des techniques d'optimisation combinatoire sont utilisées considérant les vastes domaine de recherche.

Cette approche reste néanmoins très limitée. D'une part les résultats montrent qu'elle ne permet pas d'obtenir des gains de performance en moyenne sur une suite de benchmark par rapport à la conguration standard réglée à la main. Les gains, de l'ordre de +10%, ne sont obtenus qu'en spécialisant la conguration à une instance de benchmark donnée sans prise en compte de la dépendance aux jeux de données d'entrée.

Par ailleurs la recherche d'optimum est très coûteuse. Les résultats montrent 150 heures de recherche pour une suite de 16 benchmarks sur une machine contenant susamment de ressources pour eectuer les recherches en parallèle.

Enn la limitation majeure, inhérente au caractère global des directives, concerne le ca-ractère générique des plans de compilation. L'optimum est recherché en considérant qu'un plan de compilation est global à toutes les méthodes compilées. Cette restriction limite largement le potentiel d'optimisation de code applicatif. Ainsi si les directives globales sont ecaces pour réduire le temps de démarrage de l'application, les directives localisées ore un potentiel d'optimisation plus important comme elle peuvent cibler en particulier les points chauds applicatifs et améliorer les performances asymptotiques de l'application. Heuristiques d'inlining D'autres études similaires ont été menées an de déterminer les heuristiques d'inlining optimums. Dans [22] Cavazos et Al. ont utilisé des algorithmes génétiques an de déterminer les heuristiques optimales pour l'environnement Jikes RVM. Les expérimentations ont montré une réduction du temps d'exécution de 37% pour la suite de benchmarks Dacapo sur une architecture Intel NetBurst.

Par ailleurs, l'outil JMH propose, dans sa suite de microbenchmark, un microbenchmark (JMHSample_25_API_GA) permettant de déterminer le réglage de l'inlining optimal pour la JVM HotSpot à l'aide de l'algorithme génétique de Layman.

Plus récemment, Kulkarni et Al. ont utilisé des algorithmes d'apprentissage automatiques pour construire des heuristiques d'inlining optimums [93]. Les résultats exposent un gain de 15% en moyenne sur diérents benchmarks pour la JVM HotSpot.

Ces techniques sourent des mêmes limitations soulignées dans le paragraphe précédent concernant la politique de compilation. À savoir, d'une part, la dépendance du réglage au code testé et aux jeux de données, d'autre part, le caractère général du réglage à toutes les

méthodes et enn le temps de recherche élevé. 7.2.2.2 Directives localisées

Actuellement, les étapes de compilations eectuées par un compilateur comme le com-pilateur C2 de la JVM HotSpot sont communes à toutes les méthodes, on dit que la compilation est générique par opposition à spécique. Les directives localisées permettent de régler les paramètres de compilation pour une méthode ou pour un type de méthode donnés. Elles peuvent ainsi conduire à des gains de performance à la fois en réduisant le temps de compilation (par exemple en supprimant des optimisations inecaces) et en améliorant la qualité d'exécution (en activant certaines optimisations). Les directives loca-lisées sont particulièrement utiles comme elles peuvent cibler les points chauds applicatifs et améliorer la performance asymptotique des applications.

Techniques basées sur l'apprentissage automatique Beaucoup d'études sont basées sur des techniques d'apprentissage automatique [83, 23, 148] an d'identier des heuris-tiques de sélection d'optimisations. L'apprentissage automatique a pour objectif d'identier et d'associer une sélection d'optimisation à un type de méthode déni par un vecteur de caractéristiques.

La nalité est ensuite d'intégrer ces heuristiques au sein des compilateurs dynamiques. Dans [83] par exemple, l'intégration d'heuristiques pour la sélection d'optimisation dans le compilateur C2 de HotSpot a entrainé un gain de performance de +6,2% en moyenne (+40% au maximum) sur une suite d'algorithmes génétiques.

Néanmoins, même si elles valident le potentiel du recourt à des directives locales, ces tech-niques d'apprentissage sont à ranger dans la catégorie amélioration de la compilation que l'on distingue de celle de l'optimisation de code applicatif comme vu en introduction du chapitre.

Annotation du code applicatif D'autres techniques sont basées sur l'annotation du code applicatif. Ces techniques ont par exemple été proposées aux débuts de la compilation dynamique comme une alternative à une politique de compilation gérée par l'environne-ment d'exécution [10]. L'usage d'annotation a par ailleurs été étudié pour des optimisations spéciques comme l'élimination du bound-checking [197] qui parfois n'est pas résolu dyna-miquement ou encore l'allocation de registres, qui est une optimisation coûteuse au runtime [196].

Ces techniques se rapprochent de la compilation mixte (cf. Section 7.1.4.3) comme les an-notations sont générées automatiquement par un compilateur source à source puis utilisées par le JIT au runtime.

Contrôle de la compilation Une initiative prometteuse pour l'usage de directives de compilation localisées est une amélioration intégrée dans la version Java 9 de HotSpot

baptisée compiler control [128].

L'objectif est de permettre le contrôle du compilateur dynamique à grain n et de ma-nière méthode-spécique. Même si la motivation initiale est plutôt de faciliter l'écriture de benchmarks ou de tests, elle pourra permettre également, comme démontré dans dif-férentes études [23, 148], d'améliorer les performances de l'application. L'ensemble des options contrôlables est cependant trop limité actuellement pour envisager de telles amé-liorations.

Le contrôle de la compilation est intégré dans le cadre de la technologie ReadyNow ! de la JVM propriétaire Zing (cf. Section 7.1.4.3).

7.3 Conclusion

La Table 7.1 propose une synthèse des diérentes techniques d'optimisation de code applicatif Java décrites dans ce chapitre. Les diérents critères de comparaison sont dé-nis en introduction. Le critère prix/licence n'étant pas déterminant pour la majorité des solutions, il ne gure pas dans la table.

Contrairement au critère ecacité, les critères robustesse/pérennité et diculté d'intégra-tion peuvent être bloquant dans le choix d'une solud'intégra-tion. L'ecacité d'une solud'intégra-tion repose sur quatre attributs principaux qui sont :

Son niveau d'optimisation (bytecode ou bien code natif) ;

Son niveau d'impact : impact sur les performances asymptotiques ou bien le temps de démarrage de l'application (qui traduit également la capacité à cibler les points chauds applicatif) ;

Son caractère dynamique ou statique (notamment la capacité de spécialisation du code aux données) ;

Son impact spécique à un type de code particulier (comme le polymorphisme) ou général (pouvant impacter tout type de code).

Considérant ces attributs la solution avec une ecacité optimale est donc celle permettant de faire de l'optimisation native et dynamique, de cibler les points chauds applicatifs, et d'être exploitable sur tout type de code.

Les contributions apportées sont caractérisées par un eort de développement croissant accompagné également d'une ecacité croissante. Une des contraintes qui a également guidée le choix de ces solutions et qui ne gure pas dans la table concerne la conservation de l'environnement d'exécution HotSpot pour des raisons plus larges que le critère de per-formance du code.

La meilleure alternative à court terme considérant les diérentes techniques est l'utilisation de l'API critical-native permettant l'intégration de code natif à faible coût. Les autres solu-tions comme le projet Panama ou les Snippets de Graal étant des alternatives prometteuses à plus long terme.

Catégorie Technique Pérennité/robustesse Dicultéd'intégration Ecacité Approche

JIT-Friendly

Optimisation du

polymorphisme sdépendantHotSpot- 4Java pur

4 Performance asymptotique

s Impact spécique (polymorphisme)

8 Optimisations natives Optimiseurs

de

byte-code Proguard, Soot 4En prod. 4Automatique

4 Temps de démarrage 8 Performance asymptotique 8 Optimisation native Techniques basées sur JNI Analyse JNI vs. Java avec approche JIT-friendly et me-sure des points de croisement

sPortabilité sEort de dev.

4 Optimisations natives

4 Performance asymptotique (out-of-order et alignement)

s Impact spécique (Alternative Java pour les méthodes de granularité assez forte)

8 Optimisations dynamiques Aparapi

vector-library 84Mémoire nativeAutovectorization

4 Optimisations natives

s Performance asymptotique

8 Méthode de faible granularité

8 Optimisations dynamiques jSIMD sEort de dev.

4 Optimisations natives

8 Performance asymptotique (copies systé-matiques)

8 Méthode de faible granularité

8 Pas d'optimisations dynamiques Alternatives

à JNI

GNFI 8JVM r&d

sEort de dev. 44 Optimisations nativesPerformance asymptotique

4 Méthode de faible granularité

8 Optimisations dynamiques FFI 8Projet en dev.

Critical Native sau JDKAPI interne Compilation

AOT pure Excelsior JETGCJ 48Plus d'évol.En prod. 4Automatique 84 Performance asymptotiqueRéduction temps de démarrage Compilation

mixte

AOT-JIT ART, Mono 4En prod. 8Hors Java

4 Performance asymptotique

4 Réduction temps de démarrage

Contrôle du code généré

Implémentation

d'intrinsics sPortabilité 8Eort de dev. 44 Optimisations nativesOptimisations dynamiques

4 Performance asymptotique

8 Spécialisation aux données limitée JVI s8Hors spec.Portabilité

8Expérimental 4Autovectorisation Graal Snippets 8JVM r&d 4API Java

4 Optimisations dynamiques

4 Performance asymptotique

s Spécialisation aux données

8 Optimisations natives deGoal (géné-rateur de code binaire dyna-mique) sr&d 8Hors Java 8Hors JIT 4 Optimisations natives 4 Optimisations dynamiques 4 Performance asymptotique

4 Spécialisation aux données Mint (Générateur de bytecode dy-namique) 8Extension de Java 8Hors JIT 4 Optimisations dynamiques 4 Performance asymptotique

4 Spécialisation aux données

8 Optimisations natives Contrôle

du JIT

Directives

glo-bales 4de l'applicationIndépendant 8Recherche d'op-timum dicile

s Performance asymptotique

4 Temps de démarrage

8 Limité par les capacités du JIT Directives locales

4 Performance asymptotique

4 Temps de démarrage

8 Limité par les capacités du JIT

Tab. 7.1: Analyse comparative multi-critère des techniques d'optimisation de code appli-catif Java. Les contributions apparaissent sur fond gris