Élimination d'allocations temporaires en...
Transcript of Élimination d'allocations temporaires en...
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
Élimination d'allocations temporaires en Python
Alan Raynaud
Encadré par Serge GueltonProjet de �n d'étude Telecom-Bretagne
6èmes rencontres de la communauté française de compilation
Alan Raynaud Élimination d'allocations temporaires en Python
1.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
Plan de la présentation
1 Contexte
2 Détection des allocations temporaires inutiles
3 Application à Pythran
4 Conclusion
Alan Raynaud Élimination d'allocations temporaires en Python
2.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
Les générateurs de PythonLe module itertools pour Python 2.XLe cas Python 3
Plan de la présentation
1 ContexteLes générateurs de PythonLe module itertools pour Python 2.XLe cas Python 3
2 Détection des allocations temporaires inutilesObjectifAnnotation de l'ASTAnalyse interprocéduraleRésumé
3 Application à PythranPythranApplicationRésultats
4 Conclusion
Alan Raynaud Élimination d'allocations temporaires en Python
3.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
Les générateurs de PythonLe module itertools pour Python 2.XLe 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.
Alan Raynaud Élimination d'allocations temporaires en Python
4.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
Les générateurs de PythonLe module itertools pour Python 2.XLe cas Python 3
Exemple
def squa r e ( n ) :fo r i n d e x in range ( n ) :
y i e l d n∗n
def f oo ( n ) :sum( squa r e ( n ) )
Alan Raynaud Élimination d'allocations temporaires en Python
5.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
Les générateurs de PythonLe module itertools pour Python 2.XLe 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 fo r x in range ( n ) ]
Generator Expression :
( x ∗ x fo r x in range ( n ) )
Alan Raynaud Élimination d'allocations temporaires en Python
6.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
Les générateurs de PythonLe module itertools pour Python 2.XLe cas Python 3
Le module itertools Le module itertools contient desgénérateurs pouvant être utilisés et combinés dans un programmePython.imap est équivalent à map
map( lambda x : x ∗ x , [ 0 , 1 , 2 , 3 , 4 ] )> [ 0 , 1 , 4 , 9 , 1 6 ]
izip est équivalent à zip
z i p ( [ 1 , 2 , 3 ] , [ 4 , 5 , 6 ] )> [ ( 1 , 4 ) , ( 2 , 5 ) , ( 3 , 6 ) ]
ifilter est équivalent à filter
f i l t e r ( lambda x : x < 5 , [ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 ] )> [ 1 , 2 , 3 , 4 ]
Alan Raynaud Élimination d'allocations temporaires en Python
7.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
Les générateurs de PythonLe module itertools pour Python 2.XLe cas Python 3
Performances
0
0.002
0.004
0.006
0.008
0.01
0.012
0.014
0.016
0.018
0 10000 20000 30000 40000 50000 60000 70000 80000 90000 100000
Tem
ps d
’execution
N
Somme des x2 pour x entre 1 et N
Using mapUsing imap
Alan Raynaud Élimination d'allocations temporaires en Python
8.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
Les générateurs de PythonLe module itertools pour Python 2.XLe cas Python 3
Python 3
Version de Python volontairement incompatible avec Python 2.
Changement notable : map, zip, �lter et range renvoient desgénérateurs et non plus des listes.
L'outil 2to3 e�ectue une conversion automatique mais peuoptimisée.
def f oo ( n ) :return z i p ( range ( n ) , range ( n ) )
devient
def f oo ( n ) :return l i s t ( z i p ( l i s t ( range ( n ) ) , l i s t ( range ( n ) ) ) )
Alan Raynaud Élimination d'allocations temporaires en Python
8.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
Les générateurs de PythonLe module itertools pour Python 2.XLe cas Python 3
Python 3
Version de Python volontairement incompatible avec Python 2.
Changement notable : map, zip, �lter et range renvoient desgénérateurs et non plus des listes.
L'outil 2to3 e�ectue une conversion automatique mais peuoptimisée.
def f oo ( n ) :return z i p ( range ( n ) , range ( n ) )
devient
def f oo ( n ) :return l i s t ( z i p ( l i s t ( range ( n ) ) , l i s t ( range ( n ) ) ) )
Alan Raynaud Élimination d'allocations temporaires en Python
9.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
ObjectifAnnotation de l'ASTAnalyse interprocéduraleRésumé
Plan de la présentation
1 ContexteLes générateurs de PythonLe module itertools pour Python 2.XLe cas Python 3
2 Détection des allocations temporaires inutilesObjectifAnnotation de l'ASTAnalyse interprocéduraleRésumé
3 Application à PythranPythranApplicationRésultats
4 Conclusion
Alan Raynaud Élimination d'allocations temporaires en Python
10.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
ObjectifAnnotation de l'ASTAnalyse interprocéduraleRésumé
Détection des allocations temporaires inutiles
Il y a une allocation temporaire inutile si on peut remplacer uneexpression produisant une liste par un générateur.
Objectif
Détecter les expressions pouvant êtres remplacées par ungénérateur.
Alan Raynaud Élimination d'allocations temporaires en Python
10.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
ObjectifAnnotation de l'ASTAnalyse interprocéduraleRésumé
Détection des allocations temporaires inutiles
Il y a une allocation temporaire inutile si on peut remplacer uneexpression produisant une liste par un générateur.
Objectif
Détecter les expressions pouvant êtres remplacées par ungénérateur.
Alan Raynaud Élimination d'allocations temporaires en Python
11.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
ObjectifAnnotation de l'ASTAnalyse interprocéduraleRésumé
Méthode
On parcourt l'AST (Abstract Syntax Tree) du programme Python.On va chercher à annoter les noeuds de l'AST avec une informationdu type �Peut être remplacé par un générateur�
Alan Raynaud Élimination d'allocations temporaires en Python
12.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
ObjectifAnnotation de l'ASTAnalyse interprocéduraleRésumé
Cas simples(1)
fo r e in i t e r :f oo ( e )
AST :For(expr target, expr iter, stmt* body, stmt* orelse)
On peut toujours annoter le noeud iter.
Alan Raynaud Élimination d'allocations temporaires en Python
12.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
ObjectifAnnotation de l'ASTAnalyse interprocéduraleRésumé
Cas simples(1)
fo r e in i t e r :f oo ( e )
AST :For(expr target, expr iter, stmt* body, stmt* orelse)
On peut toujours annoter le noeud iter.
Alan Raynaud Élimination d'allocations temporaires en Python
13.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
ObjectifAnnotation de l'ASTAnalyse interprocéduraleRésumé
Cas simples(2)
b1 = 5 in range (10)b2 = 5 not in range (10)
AST :Compare(expr left, cmpop op, expr comparator)
Si op = In ou NotIn, on peut annoter comparator.
Alan Raynaud Élimination d'allocations temporaires en Python
13.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
ObjectifAnnotation de l'ASTAnalyse interprocéduraleRésumé
Cas simples(2)
b1 = 5 in range (10)b2 = 5 not in range (10)
AST :Compare(expr left, cmpop op, expr comparator)
Si op = In ou NotIn, on peut annoter comparator.
Alan Raynaud Élimination d'allocations temporaires en Python
14.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
ObjectifAnnotation de l'ASTAnalyse interprocéduraleRésumé
Cas moins simple
f oo ( 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éspar des générateurs ?
Alan Raynaud Élimination d'allocations temporaires en Python
14.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
ObjectifAnnotation de l'ASTAnalyse interprocéduraleRésumé
Cas moins simple
f oo ( 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éspar des générateurs ?
Alan Raynaud Élimination d'allocations temporaires en Python
15.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
ObjectifAnnotation de l'ASTAnalyse interprocéduraleRésumé
E�ets 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 unefois.
Objectif
Déterminer les arguments véri�ant ce critère pour chaque fonction.
Alan Raynaud Élimination d'allocations temporaires en Python
15.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
ObjectifAnnotation de l'ASTAnalyse interprocéduraleRésumé
E�ets 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 unefois.
Objectif
Déterminer les arguments véri�ant ce critère pour chaque fonction.
Alan Raynaud Élimination d'allocations temporaires en Python
16.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
ObjectifAnnotation de l'ASTAnalyse interprocéduraleRésumé
Fonction de poids
On va dé�nir une fonction de poids qui renvoie le nombre de lectured'un paramètre formel d'une fonction donnée.u(foo, narg) = nombre de lecture du narg-ieme paramètre formelde foo
Alan Raynaud Élimination d'allocations temporaires en Python
17.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
ObjectifAnnotation de l'ASTAnalyse interprocéduraleRésumé
Cas des intrinsèques
Pour les intrinsèques, on dé�nit une table donnant explicitement lepoids des arguments.
Exemple :u(map,1) = 1
Alan Raynaud Élimination d'allocations temporaires en Python
17.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
ObjectifAnnotation de l'ASTAnalyse interprocéduraleRésumé
Cas des intrinsèques
Pour les intrinsèques, on dé�nit une table donnant explicitement lepoids des arguments.Exemple :u(map,1) = 1
Alan Raynaud Élimination d'allocations temporaires en Python
18.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
ObjectifAnnotation de l'ASTAnalyse interprocéduraleRésumé
Fonctions utilisateur
Méthode : On parcourt l'AST de la dé�nition de fonction pourconstruire la fonction de poids à partir des poids de chaque noeuds.
Une fois la construction de fonction de poids terminée, on peutl'évaluer pour obtenir les poids des arguments des fonctions.
Alan Raynaud Élimination d'allocations temporaires en Python
18.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
ObjectifAnnotation de l'ASTAnalyse interprocéduraleRésumé
Fonctions utilisateur
Méthode : On parcourt l'AST de la dé�nition de fonction pourconstruire la fonction de poids à partir des poids de chaque noeuds.Une fois la construction de fonction de poids terminée, on peutl'évaluer pour obtenir les poids des arguments des fonctions.
Alan Raynaud Élimination d'allocations temporaires en Python
19.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
ObjectifAnnotation de l'ASTAnalyse interprocéduraleRésumé
Exemple
def f oo (n , l1 , l 2 ) :i f (n<5):
f o r x i n l 1 : bar ( x , l 2 )e l s e :
bar (0 , l 2 )
If(cond, body, else) : cond + max(body, else)
For(iter,body) : iter + MAX * body1 if narg == 0 else 1 u(bar,1) if narg == 2 else 0
1 if narg == 1 else 0 u(bar,1) if narg == 2 else 0
Alan Raynaud Élimination d'allocations temporaires en Python
20.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
ObjectifAnnotation de l'ASTAnalyse interprocéduraleRé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
Alan Raynaud Élimination d'allocations temporaires en Python
21.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
ObjectifAnnotation de l'ASTAnalyse interprocéduraleRésumé
Resumé
1 On calcule les fonctions de poids : directement pour lesintrinsè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.
Alan Raynaud Élimination d'allocations temporaires en Python
22.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
PythranApplicationRésultats
Plan de la présentation
1 ContexteLes générateurs de PythonLe module itertools pour Python 2.XLe cas Python 3
2 Détection des allocations temporaires inutilesObjectifAnnotation de l'ASTAnalyse interprocéduraleRésumé
3 Application à PythranPythranApplicationRésultats
4 Conclusion
Alan Raynaud Élimination d'allocations temporaires en Python
23.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
PythranApplicationRé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 desdirectives openMP.
Alan Raynaud Élimination d'allocations temporaires en Python
24.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
PythranApplicationRésultats
Chaine de compilation
Python Module [.py] Type InfoOpenMP
Pythran
C++boost::python pythonic++
g++
Native Module [.so]
Alan Raynaud Élimination d'allocations temporaires en Python
25.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
PythranApplicationRésultats
Pertinence
0
0.0005
0.001
0.0015
0.002
0.0025
0.003
0.0035
0.004
0.0045
0 100000 200000 300000 400000 500000 600000 700000 800000 900000 1e+06
Tem
ps d
’execution
N
Somme des x2 pour x entre 1 et N
En utilisant mapEn utilisant imap
Alan Raynaud Élimination d'allocations temporaires en Python
26.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
PythranApplicationRésultats
Insertion dans la chaine de compilation
Pythran dispose d'une phase d'optimisation qui travaille sur l'ASTdu programme Python avant la conversion en C++.
Réduction des expressions constantes.
Transformation des List Comprehension en combinaison defonctions.
Transformation des Generator Expressions en combinaison degénérateurs itertools.
Alan Raynaud Élimination d'allocations temporaires en Python
27.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
PythranApplicationRésultats
Optimisations à réaliser
range -> xrange
Fonction -> Équivalent itertools
List Comprehensions -> Generator Expressions
Alan Raynaud Élimination d'allocations temporaires en Python
28.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
PythranApplicationRésultats
Transformation des List Comprehension
Transformation triviale : remplacer un noeud ast.ListComp par unast.GeneratorExpression.
Alan Raynaud Élimination d'allocations temporaires en Python
29.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
PythranApplicationRésultats
Transformation des fonctions
Transformation moins triviale
def range ( n ) :foo = z i preturn map( lambda x , y : x∗y , foo ( range ( n ) , range ( n ) ) )
def bar ( n ) :return sum( range ( n ) )
Alan Raynaud Élimination d'allocations temporaires en Python
30.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
PythranApplicationRésultats
Cas particuliers
0
0.002
0.004
0.006
0.008
0.01
0.012
0.014
0.016
0.018
0 100000 200000 300000 400000 500000 600000 700000 800000 900000
tim
e
n
sum(map(lambda (x,y) : x+y, zip(range(n), range(n))))
With optimizationWithout optimization
Alan Raynaud Élimination d'allocations temporaires en Python
31.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
PythranApplicationRésultats
Cas moyen
Problème : Combien y a-t'il d'allocations temporaires inutiles dansun programme moyen ?
Su�samment pour justi�er les choix de Python 3.
Alan Raynaud Élimination d'allocations temporaires en Python
31.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
PythranApplicationRésultats
Cas moyen
Problème : Combien y a-t'il d'allocations temporaires inutiles dansun programme moyen ?Su�samment pour justi�er les choix de Python 3.
Alan Raynaud Élimination d'allocations temporaires en Python
32.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
Plan de la présentation
1 ContexteLes générateurs de PythonLe module itertools pour Python 2.XLe cas Python 3
2 Détection des allocations temporaires inutilesObjectifAnnotation de l'ASTAnalyse interprocéduraleRésumé
3 Application à PythranPythranApplicationRésultats
4 Conclusion
Alan Raynaud Élimination d'allocations temporaires en Python
33.0
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
Conclusion
Appliqué à Pythran, la méthode permet des gains deperformances signi�catifs dans les cas qui s'y prêtent.
D'autres applications sont possibles, comme l'amélioration de2to3, le convertisseur Python 2 vers Python 3.
Alan Raynaud Élimination d'allocations temporaires en Python
ContexteDétection des allocations temporaires inutiles
Application à PythranConclusion
Résumé
Contexte
En Python l'allocation de mémoire temporaire à un coût enperformances, 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 ungénérateur.
Calcul de fonctions de poids pour déterminer si les argumentspassé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