Élimination d`allocations temporaires en Python

publicité
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Élimination d'allocations temporaires en Python
Alan Raynaud
Encadré par Serge Guelton
Projet de n d'étude Telecom-Bretagne
6èmes rencontres de la communauté française de compilation
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Plan de la présentation
1
Contexte
2
Détection des allocations temporaires inutiles
3
Application à Pythran
4
Conclusion
1.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Les générateurs de Python
Le module
itertools
pour Python 2.X
Le cas Python 3
Plan de la présentation
1
Contexte
Les générateurs de Python
Le module
itertools
pour Python 2.X
Le cas Python 3
2
Détection des allocations temporaires inutiles
Objectif
Annotation de l'AST
Analyse interprocédurale
Résumé
3
Application à Pythran
Pythran
Application
Résultats
2.0
4
Conclusion
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Les générateurs de Python
Le module
itertools
pour Python 2.X
Le cas Python 3
Description (informelle) d'un générateur
Un générateur est un objet se comportant comme un itérateur,
mais qui créé ses valeurs à la volée.
3.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Les générateurs de Python
Le module
itertools
pour Python 2.X
Le cas Python 3
Exemple
def s q u a r e ( n ) :
for index in
yield
def
range (n ) :
n∗n
foo (n ) :
sum ( s q u a r e ( n ) )
4.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Les générateurs de Python
Le module
itertools
pour Python 2.X
Le cas Python 3
List Comprehension et Generator Expression
Syntaxe concise permettant de créer des listes ou des générateurs.
List Comprehension :
[x
∗
x
for
x
in
range (n ) ]
Generator Expression :
(x
∗
x
for
x
in
range (n ))
5.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Les générateurs de Python
Détection des allocations temporaires inutiles
Le module
Application à Pythran
Le module itertools
itertools
pour Python 2.X
Le cas Python 3
Conclusion
Le module
itertools
contient des
générateurs pouvant être utilisés et combinés dans un programme
Python.
imap
est équivalent à
map ( lambda
>
x
est équivalent à
zip ([1 ,2 ,3] ,
[(1 ,4) ,
ifilter
x,
[0 ,1 ,2 ,3 ,4])
zip
[4 ,5 ,6])
(2 ,5) ,
(3 ,6)]
est équivalent à
f i l t e r ( lambda
>
∗
x
[0 ,1 ,4 ,9 ,16]
izip
>
:
map
x
:
filter
x < 5,
[1 ,2 ,3 ,4 ,5 ,6 ,7 ,8])
[1 ,2 ,3 ,4]
6.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Les générateurs de Python
Le module
itertools
pour Python 2.X
Le cas Python 3
Performances
Somme des x2 pour x entre 1 et N
0.018
Using map
Using imap
0.016
0.014
Temps d’execution
0.012
0.01
0.008
0.006
0.004
0.002
0
0
10000
20000
30000
40000
50000
N
60000
70000
80000
90000
100000
7.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Les générateurs de Python
Le module
itertools
pour Python 2.X
Le cas Python 3
Python 3
Version de Python volontairement incompatible avec Python 2.
Changement notable : map, zip, lter et range renvoient des
générateurs et non plus des listes.
L'outil 2to3 eectue une conversion automatique mais peu
optimisée.
8.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Les générateurs de Python
Le module
itertools
pour Python 2.X
Le cas Python 3
Python 3
Version de Python volontairement incompatible avec Python 2.
Changement notable : map, zip, lter et range renvoient des
générateurs et non plus des listes.
L'outil 2to3 eectue une conversion automatique mais peu
optimisée.
def f o o ( n ) :
return z i p ( range (n ) , range (n ))
devient
def f o o ( n ) :
return l i s t ( z i p ( l i s t ( range (n )) , l i s t ( range (n ) ) ) )
8.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Objectif
Annotation de l'AST
Analyse interprocédurale
Résumé
Plan de la présentation
1
Contexte
Les générateurs de Python
Le module
itertools
pour Python 2.X
Le cas Python 3
2
Détection des allocations temporaires inutiles
Objectif
Annotation de l'AST
Analyse interprocédurale
Résumé
3
Application à Pythran
Pythran
Application
Résultats
4
Conclusion 9.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Objectif
Annotation de l'AST
Analyse interprocédurale
Résumé
Détection des allocations temporaires inutiles
Il y a une allocation temporaire inutile si on peut remplacer une
expression produisant une liste par un générateur.
10.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Objectif
Annotation de l'AST
Analyse interprocédurale
Résumé
Détection des allocations temporaires inutiles
Il y a une allocation temporaire inutile si on peut remplacer une
expression produisant une liste par un générateur.
Objectif
Détecter les expressions pouvant êtres remplacées par un
générateur.
10.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Objectif
Annotation de l'AST
Analyse interprocédurale
Résumé
Méthode
On parcourt l'AST (Abstract Syntax Tree) du programme Python.
On va chercher à annoter les noeuds de l'AST avec une information
du type Peut être remplacé par un générateur
11.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Objectif
Annotation de l'AST
Analyse interprocédurale
Résumé
Cas simples(1)
for
e
in
iter :
foo ( e )
AST :
For(expr target, expr iter, stmt* body, stmt* orelse)
12.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Objectif
Annotation de l'AST
Analyse interprocédurale
Résumé
Cas simples(1)
for
e
in
iter :
foo ( e )
AST :
For(expr target, expr iter, stmt* body, stmt* orelse)
On peut toujours annoter le noeud iter.
12.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Objectif
Annotation de l'AST
Analyse interprocédurale
Résumé
Cas simples(2)
b1 = 5
b2 = 5
in range (10)
not i n r a n g e ( 1 0 )
AST :
Compare(expr left, cmpop op, expr comparator)
13.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Objectif
Annotation de l'AST
Analyse interprocédurale
Résumé
Cas simples(2)
b1 = 5
b2 = 5
in range (10)
not i n r a n g e ( 1 0 )
AST :
Compare(expr left, cmpop op, expr comparator)
Si op = In ou NotIn, on peut annoter comparator.
13.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Objectif
Annotation de l'AST
Analyse interprocédurale
Résumé
Cas moins simple
foo (a , b , c )
AST :
Call(expr func, expr* args, keyword* keywords, expr?
starargs, expr? kwargs)
14.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Objectif
Annotation de l'AST
Analyse interprocédurale
Résumé
Cas moins simple
foo (a , b , c )
AST :
Call(expr func, expr* args, keyword* keywords, expr?
starargs, expr? kwargs)
Problème : comment savoir si les arguments peuvent être remplacés
par des générateurs ?
14.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Objectif
Annotation de l'AST
Analyse interprocédurale
Résumé
Eets des fonctions sur leurs arguments
Proposition : Un argument passé à une fonction peut être remplacé
par un générateur s'il n'est jamais modié et s'il est lu au plus une
fois.
15.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Objectif
Annotation de l'AST
Analyse interprocédurale
Résumé
Eets des fonctions sur leurs arguments
Proposition : Un argument passé à une fonction peut être remplacé
par un générateur s'il n'est jamais modié et s'il est lu au plus une
fois.
Objectif
Déterminer les arguments vériant ce critère pour chaque fonction.
15.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Objectif
Annotation de l'AST
Analyse interprocédurale
Résumé
Fonction de poids
On va dénir une fonction de poids qui renvoie le nombre de lecture
d'un paramètre formel d'une fonction donnée.
u(foo, narg) = nombre de lecture du narg-ieme paramètre formel
de foo
16.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Objectif
Détection des allocations temporaires inutiles
Annotation de l'AST
Application à Pythran
Analyse interprocédurale
Conclusion
Résumé
Cas des intrinsèques
Pour les intrinsèques, on dénit une table donnant explicitement le
poids des arguments.
17.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Objectif
Détection des allocations temporaires inutiles
Annotation de l'AST
Application à Pythran
Analyse interprocédurale
Conclusion
Résumé
Cas des intrinsèques
Pour les intrinsèques, on dénit une table donnant explicitement le
poids des arguments.
Exemple :
u(map,1) = 1
17.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Objectif
Annotation de l'AST
Analyse interprocédurale
Résumé
Fonctions utilisateur
Méthode : On parcourt l'AST de la dénition de fonction pour
construire la fonction de poids à partir des poids de chaque noeuds.
18.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Objectif
Annotation de l'AST
Analyse interprocédurale
Résumé
Fonctions utilisateur
Méthode : On parcourt l'AST de la dénition de fonction pour
construire la fonction de poids à partir des poids de chaque noeuds.
Une fois la construction de fonction de poids terminée, on peut
l'évaluer pour obtenir les poids des arguments des fonctions.
18.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Objectif
Annotation de l'AST
Analyse interprocédurale
Résumé
Exemple
def f o o ( n , l 1 , l 2 ) :
i f ( n <5):
for x in l 1 : bar ( x , l 2 )
else :
bar (0 , l 2 )
If(cond, body, else) : cond + max(body, else)
1 if narg == 0 else 1
For(iter,body) : iter + MAX * body
1 if narg == 1 else 0
u(bar,1) if narg == 2 else 0
u(bar,1) if narg == 2 else 0
19.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Objectif
Annotation de l'AST
Analyse interprocédurale
Résumé
Cycles et recursivité
Pour détecter les cycles, on mémorise le chemin lors de l'évaluation.
(suite des appels à une autre fonction de poids).
Exemple :
foo -> bar -> jo -> foo -> ...
On estime le poids total du cycle de la façon suivante :
Poids total = MAX * poids partiel
20.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Objectif
Annotation de l'AST
Analyse interprocédurale
Résumé
Resumé
1
On calcule les fonctions de poids : directement pour les
intrinsèques, en parcourant l'AST pour les fonctions utilisateur.
2
On évalue les poids des arguments de toutes les fonctions.
3
On annote l'AST : directement pour les noeuds NotIn, In, et
For. Si le poids est <=1 pour les arguments des noeuds Call.
21.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Pythran
Application
Résultats
Plan de la présentation
1
Contexte
Les générateurs de Python
Le module
itertools
pour Python 2.X
Le cas Python 3
2
Détection des allocations temporaires inutiles
Objectif
Annotation de l'AST
Analyse interprocédurale
Résumé
3
Application à Pythran
Pythran
Application
Résultats
4
Conclusion
22.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Pythran
Application
Résultats
Pythran en bref
Pythran :
Traduit un sous-ensemble de Python vers C++
Génère des modules utilisables depuis Python
Permet la parallélisation des opérations en utilisant des
directives openMP.
23.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Pythran
Application
Résultats
Chaine de compilation
OpenMP
Python Module [.py]
Type Info
Pythran
boost::python
C++
pythonic++
g++
Native Module [.so]
Alan Raynaud
24.0
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Pythran
Application
Résultats
Pertinence
Somme des x2 pour x entre 1 et N
0.0045
En utilisant map
En utilisant imap
0.004
0.0035
Temps d’execution
0.003
0.0025
0.002
0.0015
0.001
0.0005
0
0
100000 200000 300000 400000 500000 600000 700000 800000 900000
N
1e+06
25.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Pythran
Application
Résultats
Insertion dans la chaine de compilation
Pythran dispose d'une phase d'optimisation qui travaille sur l'AST
du programme Python avant la conversion en C++.
Réduction des expressions constantes.
Transformation des List Comprehension en combinaison de
fonctions.
Transformation des Generator Expressions en combinaison de
générateurs itertools.
26.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Pythran
Application
Résultats
Optimisations à réaliser
range
->
xrange
Fonction -> Équivalent
itertools
List Comprehensions -> Generator Expressions
27.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Pythran
Application
Résultats
Transformation des List Comprehension
Transformation triviale : remplacer un noeud
ast.GeneratorExpression.
ast.ListComp
par un
28.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Pythran
Application
Résultats
Transformation des fonctions
Transformation moins triviale
def r a n g e ( n ) :
foo = zip
r e t u r n map ( lambda x , y : x ∗ y , f o o ( r a n g e ( n ) , r a n g e ( n ) ) )
def b a r ( n ) :
r e t u r n sum ( r a n g e ( n ) )
29.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Pythran
Détection des allocations temporaires inutiles
Application
Application à Pythran
Résultats
Conclusion
Cas particuliers
sum(map(lambda (x,y) : x+y, zip(range(n), range(n))))
0.018
With optimization
Without optimization
0.016
0.014
0.012
time
0.01
0.008
0.006
0.004
0.002
0
0
100000
200000
300000
400000
500000
600000
700000
800000
900000
n
30.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Pythran
Application
Résultats
Cas moyen
Problème : Combien y a-t'il d'allocations temporaires inutiles dans
un programme moyen ?
31.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Pythran
Application
Résultats
Cas moyen
Problème : Combien y a-t'il d'allocations temporaires inutiles dans
un programme moyen ?
Susamment pour justier les choix de Python 3.
31.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Plan de la présentation
1
Contexte
Les générateurs de Python
Le module
itertools
pour Python 2.X
Le cas Python 3
2
Détection des allocations temporaires inutiles
Objectif
Annotation de l'AST
Analyse interprocédurale
Résumé
3
Application à Pythran
Pythran
Application
Résultats
4
Conclusion
32.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Conclusion
Appliqué à Pythran, la méthode permet des gains de
performances signicatifs dans les cas qui s'y prêtent.
D'autres applications sont possibles, comme l'amélioration de
2to3, le convertisseur Python 2 vers Python 3.
33.0
Alan Raynaud
Élimination d'allocations temporaires en Python
Contexte
Détection des allocations temporaires inutiles
Application à Pythran
Conclusion
Résumé
Contexte
En Python l'allocation de mémoire temporaire à un coût en
performances, mais il existe des outils pour y remédier.
Détection de mémoire temporaire inutile
Annotation des noeuds de l'AST où on pourrait utiliser un
générateur.
Calcul de fonctions de poids pour déterminer si les arguments
passés à une fonction peuvent être annotés.
Application à Pythran
Implémentation de l'algorithme en Python.
Transformations éliminant les allocations temporaires inutiles.
Alan Raynaud
Élimination d'allocations temporaires en Python
Téléchargement