Demat i'Nal,
J'ai publié ce matin une nouvelle mouture du compilateur pour codes scientifiques écrits en Python nommé Pythran. C'est la version 0.13.0 et elle porte le joli sobriquet bouch'hal.
Les plus impatients téléchargeront immédiatement la dernière version sur PyPi ou Github tandis que les plus curieux s'empresseront de lire le changelog associé.
Mais ce serait louper la suite de ce billet, où j'aimerai vous parler des bienfaits de l'émulation. Lors de ma veille, je suis tombé sur le projet de compilateur pyccel qui partage plusieurs caractéristiques avec le projet Pythran : compilateur source à source, en avance de phase, ciblant le calcul numérique. Avec quelques différences : support (encore plus) limité des constructions Numpy et du langage Python, mais surtout possibilité d'utilisé C ou Fortran comme langage cible. Sympa !
Ce projet a publié une suite de benchmark permettant des points de comparaison avec Pythran. Et sur certains noyaux, Pythran n'était vraiment pas bon. J'ai creusé un peu (car oui, mon ego en a pris un coup) et de manière fascinante, les compilateurs clang et gcc peinent à générer un code équivalent pour les deux fonctions C++ suivantes (cf. godbolt pour les plus saint Thomas d'entre vous):
long ackermann(long m, long n) {
if (m == 0)
return n + 1;
if (n == 0)
return ackermann(m - 1, 1)
return ackermann(m - 1, ackermann(m, n - 1));
}
et
static long ack(long const& m, long const& n) {
if (m == 0)
return n + 1;
if (n == 0)
return ack(m - 1, 1);
return ack(m - 1, ack(m, n - 1));
}
long ackermann(long m, long n) { return ack(m, n); }
Pythran générant du code générique, il m'a fallu pas mal d'heures de réflexions pour circonvenir le problème et arriver à un patch. Mais c'est bon, problème de performance corrigé !
# autre compilo python : codon
Posté par Thomas Douillard . Évalué à 4.
Je sais pas si tu as vu passer codon dans ta veille : https://github.com/exaloop/codon
C'est un compilateur, natif par contre, ils clament de gros gains de perfs et une couverture de python importante.
[^] # Re: autre compilo python : codon
Posté par serge_sans_paille (site web personnel) . Évalué à 3.
Vu dans les sources de condon:
[^] # Re: autre compilo python : codon
Posté par steph1978 . Évalué à 3.
Plutôt normal, c'est déjà compilé en natif.
C'est pour dire que Pythran devait donc être plus rapide car plus rapide que Numpy ?
[^] # Re: autre compilo python : codon
Posté par steph1978 . Évalué à 3.
J'ai joué avec à l'occasion du advent of code.
the good
Les gains peuvent atteindre 100x.
the bad
Les modules ne sont pas compilés à la volé, ils doivent l'être en amont. Par conséquent peu de modules sont implémentés en natif, pour le reste il faut se rabattre sur l'interprété.
the ugly
L'import d'un module non natif passe par un
from python import module
au lieu deimport module
. Ce qui fait qu'un script ne peut pas être écrit pour les deux, python et codon, dommage.[^] # Re: autre compilo python : codon
Posté par serge_sans_paille (site web personnel) . Évalué à 2.
J'ai regardé ton code (pas possible de reproduire les perfs, il me manque le fichier d'entrée et une valeur pour le nombre de round) et le gain de x100 n'est pas surprenant : double boucle imbriquée, le cas parfait pour les compilos statiques ;-)
Note que ça n'enlève rien aux mérites de condon hein, juste pour dire que c'est un point ou cPython ne brille pas et où tout compilateur pour Python devrait s'en sortir plutôt bien. Le support des générateurs et d'expression du style
next(filter(lambda m: m[1], moves))[0]
c'est chouette (et c'est aussi dans pythran bien sûr ;-))Je trouve la liste des modules supportés plutôt respectable !
[^] # Re: autre compilo python : codon
Posté par steph1978 . Évalué à 2.
Mon input est ici
Il faut 1025 round pour arriver à un état stable. Ça prend 0.85s sur ma machine contre 7.57s en python 3.11. Pas du tout 100x, donc, mais plutôt 10x.
Faudrait que je retrouve mon cas à 100x… Bref.
# Mais pourquoi ?
Posté par Julien Jorge (site web personnel) . Évalué à 5.
Intéressant, mais pourquoi le compilateur a-t-il du mal à générer le même code ?
[^] # Re: Mais pourquoi ?
Posté par serge_sans_paille (site web personnel) . Évalué à 4.
Bonne question! Si on regarde précisément le code sans passage par référence, on voit qu'une des deux récursions a été transformée en boucle, on peut imaginer une contrainte sur l'analyse d'aliasing ?
[^] # Re: Mais pourquoi ?
Posté par Julien Jorge (site web personnel) . Évalué à 5.
J'aurais misé sur une histoire d'aliasing aussi mais vu que les valeurs des paramètres ne sont pas modifiés par les appels je ne vois pas comment ça pourrait être un problème.
Est-ce que ça pourrait être l'inlining ? Si le compilo considère que
ack
peut être « inlinée » dansackermann
, est-ce qu'il n'essaye pas aussi d'inliner les appels récursifs dans la foulée et conclut que ça ne passe pas ?En tout cas je me dis qu'on fait peut-être un peu trop confiance au compilateur pour les optims. Ça vaut le coup de vérifier l'assembleur émis :)
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.