Dans le but d’améliorer les performances du langage de programmation Python, Microsoft lance Faster CPython. Il s’agit d’un projet financé par Microsoft, dont les membres comprennent l'inventeur de Python Guido van Rossum, l'ingénieur logiciel senior de Microsoft Eric Snow, et Mark Shannon qui est sous contrat avec Microsoft en tant que responsable technique du projet. « Python est largement reconnu comme étant lent. Alors que Python n'atteindra jamais les performances des langages de bas niveau comme C, Fortran, ou même Java, nous aimerions qu'il soit compétitif avec les implémentations rapides des langages de script, comme V8 pour Javascript », déclare Mark Shannon.
Pour être performantes, les machines virtuelles pour les langages dynamiques doivent spécialiser le code qu'elles exécutent en fonction des types et des valeurs du programme en cours d'exécution. Cette spécialisation est souvent associée aux compilateurs Just-in-time (JIT), mais elle est bénéfique même sans génération de code machine.
Notons que la spécialisation permet d'améliorer les performances, et l'adaptation permet à l'interprète de changer rapidement lorsque le modèle d'utilisation d'un programme change, limitant ainsi la quantité de travail supplémentaire causée par une mauvaise spécialisation.
Une session prévue dans le cadre de l'événement EuroPython, la plus grande conférence Python en Europe, qui se tiendra à Dublin en juillet sera consacrée à certains des changements qui permettent d'accélérer le processus. Shannon décrira l'adaptive specializing interpreter de Python 3.11, qui est le PEP (Python Enhancement Proposal) 659. Il s'agit d'une technique appelée spécialisation qui, comme l'explique Shannon, « est généralement réalisée dans le contexte d'un compilateur, mais la recherche montre que la spécialisation dans un interpréteur peut augmenter les performances de manière significative ».
Ce PEP propose d'utiliser un interprète adaptatif qui spécialise le code de manière dynamique, mais sur une très petite région, et qui est capable de s'adapter à une mauvaise spécialisation rapidement et à faible coût.
« L'ajout d'un interprète spécialisé et adaptatif à CPython apportera des améliorations significatives en termes de performances. Il est difficile d'avancer des chiffres significatifs, car cela dépend beaucoup des benchmarks et de travaux qui n'ont pas encore été réalisés. Des expérimentations approfondies suggèrent des accélérations allant jusqu'à 50 %. Même si le gain de vitesse n'était que de 25 %, cela resterait une amélioration intéressante », déclare Shannon.
« Plus précisément, nous voulons atteindre ces objectifs de performance avec CPython afin d'en faire bénéficier tous les utilisateurs de Python, y compris ceux qui ne peuvent pas utiliser PyPy ou d'autres machines virtuelles alternatives », ajoute-il. Lorsque Devclass s'est entretenu avec Pablo Galindo, membre du conseil de direction de Python et développeur principal, au sujet du nouveau profileur de mémoire Memray, il a décrit comment l'équipe Python utilise le travail de Microsoft dans la version 3.11.
« L'une des choses que nous faisons est que nous rendons l'interpréteur plus rapide, déclare Pablo Galindo, membre du conseil de direction de Python et développeur principal. Mais il va également utiliser un peu plus de mémoire, juste un peu, parce que la plupart de ces optimisations ont une sorte de coût en mémoire, étant donné que nous devons stocker des choses pour les utiliser plus tard, ou parce que nous avons une version optimisée mais parfois, quelqu'un a besoin de demander une version non optimisée pour le débogage, donc nous devons stocker les deux. »
« Atteindre ces objectifs de performance est un long chemin à parcourir, et nécessitera beaucoup d'efforts d'ingénierie, mais nous pouvons faire un pas significatif vers ces objectifs en accélérant l'interpréteur. La recherche universitaire et les mises en œuvre pratiques ont montré qu'un interpréteur rapide est un élément clé d'une machine virtuelle rapide », déclare Shannon.
Accélération des machines virtuelles
Les optimisations typiques pour les machines virtuelles sont coûteuses, de sorte qu'un long temps de "démarrage" est nécessaire pour avoir la certitude que le coût de l'optimisation est justifié. Afin d'obtenir des accélérations rapides, sans temps d'échauffement perceptible, la VM devrait spéculer que la spécialisation est justifiée même après quelques exécutions d'une fonction. Pour ce faire, l'interpréteur doit être capable d'optimiser et de désoptimiser continuellement et à moindre coût. En utilisant la spécialisation adaptative et spéculative à la granularité des instructions individuelles de la machine virtuelle, l’équipe Python a obtenu un interprète plus rapide qui génère également des informations de profilage pour des optimisations plus sophistiquées dans le futur.
« Il existe de nombreuses façons pratiques d'accélérer une machine virtuelle pour un langage dynamique. Cependant, la spécialisation est la plus importante, à la fois en elle-même et en tant que catalyseur d'autres optimisations. Il est donc logique de concentrer nos efforts sur la spécialisation en premier lieu, si nous voulons améliorer les performances de CPython », indique l’équipe du projet Faster CPython. La spécialisation est généralement effectuée dans le contexte d'un compilateur JIT, mais des recherches montrent que la spécialisation dans un interpréteur peut améliorer les performances de manière significative, voire même dépasser celles d'un compilateur classique.
Plusieurs méthodes ont été proposées dans la littérature académique, mais la plupart tentent d'optimiser des domaines plus grands qu'un seul bytecode. L'utilisation de domaines plus grands qu'une seule instruction nécessite un code pour gérer la désoptimisation au milieu d'un domaine. La spécialisation au niveau des bytecodes individuels rend la désoptimisation triviale, car elle ne peut pas se produire au milieu d'une région.
En spécialisant de manière spéculative les bytecodes individuels, nous pouvons obtenir des améliorations de performance significatives sans rien d'autre que les désoptimisations les plus locales et triviales à mettre en œuvre. L'approche la plus proche de ce PEP dans la littérature est "Inline Caching meets Quickening". Ce PEP présente les avantages de la mise en cache en ligne, mais ajoute la possibilité de désoptimiser rapidement, ce qui rend les performances plus robustes dans les cas où la spécialisation échoue ou n'est pas stable.
L'accélération due à la spécialisation est difficile à déterminer, car de nombreuses spécialisations dépendent d'autres optimisations. Les gains de vitesse semblent se situer entre 10 % et 60 %. La plupart des gains de vitesse proviennent directement de la spécialisation. Les plus grands contributeurs étant les accélérations de la recherche d'attributs, des variables globales et des appels.
Implémentation
Instructions adaptatives
Chaque instruction qui bénéficierait d'une spécialisation est remplacée par une version adaptative lors du quickening. Par exemple, l'instruction LOAD_ATTR est remplacée par LOAD_ATTR_ADAPTIVE. Chaque instruction adaptative tente périodiquement de se spécialiser.
Spécialisation
Le bytecode CPython contient de nombreuses instructions qui représentent des opérations de haut niveau, et qui bénéficieraient d'une spécialisation. Les exemples incluent CALL, LOAD_ATTR, LOAD_GLOBAL et BINARY_ADD.
L'introduction d'une catégorie d'instructions spécialisées pour chacune de ces instructions permet une spécialisation efficace, puisque chaque nouvelle instruction est spécialisée pour une seule tâche. Chaque famille comprendra une instruction "adaptative", qui maintient un compteur et tente de se spécialiser lorsque ce compteur atteint zéro. Chaque catégorie comprendra également une ou plusieurs instructions spécialisées qui exécutent l'équivalent de l'opération générique beaucoup plus rapidement, à condition que leurs entrées soient conformes aux prévisions.
Chaque instruction spécialisée maintient un compteur de saturation qui est incrémenté lorsque les entrées sont conformes aux attentes. Si les entrées ne sont pas conformes aux attentes, le compteur sera décrémenté et l'opération générique sera exécutée. Si le compteur atteint la valeur minimale, l'instruction est désoptimisée en remplaçant simplement son opcode par la version adaptative.
Données auxiliaires
La plupart des familles d'instructions spécialisées requièrent plus d'informations que ne peut en contenir un opérande de 8 bits. Pour ce faire, un certain nombre d'entrées de 16 bits suivant immédiatement l'instruction sont utilisées pour stocker ces données. Il s'agit d'une forme de cache en ligne, un "cache de données en ligne". Les instructions non spécialisées, ou adaptatives, utiliseront la première entrée de ce cache comme compteur, et sauteront simplement les autres.
Coûts
Utilisation de la mémoire
Une préoccupation évidente avec tout système qui effectue une sorte de mise en cache est : combien de mémoire supplémentaire utilise-t-il ?
Comparaison de l'utilisation de la mémoire avec 3.10
CPython 3.10 utilisait 2 octets par instruction, jusqu'à ce que le nombre d'exécutions atteigne ~2000 lorsqu'il alloue un autre octet par instruction et 32 octets par instruction avec un cache (LOAD_GLOBAL et LOAD_ATTR).
Le tableau suivant montre les octets supplémentaires par instruction pour supporter l'opcache 3.10 ou l'interprète adaptatif proposé, sur une machine 64 bits.
3.10 cold est avant que le code n'ait atteint la limite de ~2000. 3.10 hot montre l'utilisation du cache une fois que le seuil est atteint. L'utilisation relative de la mémoire dépend de la quantité de code qui est suffisamment "hot" pour déclencher la création du cache dans 3.10. Le point d'équilibre, où la mémoire utilisée par 3.10 est la même que pour 3.11, est de ~70%. Il convient également de noter que le bytecode réel n'est qu'une partie d'un objet de code. Les objets de code comprennent également des noms, des constantes et un grand nombre d'informations de débogage.
En résumé, pour la plupart des applications où de nombreuses fonctions sont relativement inutilisées, la version 3.11 consommera plus de mémoire que la version 3.10.
Source : Python
Et vous ?
Quel est votre avis sur le sujet ?
Que pensez-vous du projet Faster CPython ?
« La version 3.11 consommera plus de mémoire que la version 3.10 », qu’en pensez-vous ?
Selon vous, est intéressent de gagner en performance au prix d'un peu plus de mémoire ?
Voir aussi :
Python 3.11 améliorera l'emplacement des erreurs dans les tracebacks et apporte de nouvelles fonctionnalités
La version 3.2 du framework Django est disponible, avec la découverte automatique d'AppConfig, elle apporte de nouveaux décorateurs pour le module d'administration
Django 2.0 est disponible en version stable, quelles sont les nouveautés dans cette version du framework Web écrit en Python ?
JetBrains soutient Django : bénéficiez d'une remise de 30 % pour l'achat d'une licence individuelle PyCharm Professional et l'intégralité des sommes perçues seront reversées à la Fondation Django
Python 3.11 gagnera en performance au prix d'un peu plus de mémoire,
Les gains de vitesse semblent se situer entre 10 % et 60 %
Python 3.11 gagnera en performance au prix d'un peu plus de mémoire,
Les gains de vitesse semblent se situer entre 10 % et 60 %
Le , par Bruno
Une erreur dans cette actualité ? Signalez-nous-la !