Table of Contents

Profilage de code sous Linux

gprof

Description

Il s'agit d'un programme de profilage pour des codes en C/C++.

Utilisation

On se retrouve alors avec un fichier texte (profil.txt) dont la syntaxe ressemble à ceci :

Profile plat:
Chaque échantillon dénombre 0.01 seconds.
%    cumulatif   auto              auto     total
temps   seconds   seconds   appels  s/appel  s/appel  nom
13.72      1.62     1.62                             MatSetValues_SeqAIJ(_p_Mat*, int, int const*, int, int const*, double const*, InsertMode)
4.23      2.12     0.50   412564     0.00     0.00  Llist<Phys_Elem*, Compare_Elem>::get(Phys_Elem*&) const
3.26      2.51     0.39  1374974     0.00     0.00  Compare_Elem::equal(Phys_Elem const*, Phys_Elem const*)
3.13      2.88     0.37  3184640     0.00     0.00  Phys_Elem::get_elem_id() const
2.71      3.20     0.32    25501     0.00     0.00  FEP_Meca::calc_element_matrix_2(Mymatrix<double>&, Positions&, Myvector<double>&, Field<double>*)
2.62      3.51     0.31        7     0.04     0.35  Field<double>::print_2D_slice_gmsh(FE_Mesh&, GE_Plane&, Physical_Region const&, std::string)
2.37      3.79     0.28        1     0.28     2.15  FEP_Meca::fill_system(Field<double>*, Field<double>*, Field<double>*, double, double)
2.37      4.07     0.28  4765233     0.00     0.00  Point::z() const
2.29      4.34     0.27  3682784     0.00     0.00  Phys_Elem::get_part_elem_id() const
2.24      4.60     0.27  1989078     0.00     0.00  Real_Tensor::dot(Real_Tensor const&) const
2.12      4.85     0.25  7335450     0.00     0.00  Phys_Elem::get_region_id() const
[...]

C'est très convivial. Il y a moyen de déchiffrer le fichier, en tout cas de déterminer les quelques fonctions les plus gourmandes en temps de calcul, mais ça devient vite éprouvant. Il existe une interface graphique appelée Gprof2Dot qui crée des graphes beaucoup plus lisibles à partir du fichier de sortie de gprof (entre autres). J'ai peu testé cette interface parce que je ne suis arrivé à créer de graphes que pour de très petits programmes. Metafor, je n'ai même pas tenté. Il y a peut-être moyen d'en tirer quelque chose en jouant avec les options.

Références

gprof, Gprof2Dot.

valgrind

Description

Il s'agit en fait d'une suite d'outils pour détecter des problèmes de mémoire, comme des fuites ou des accès invalides, ou réaliser le profilage d'un code à l'aide de différentes méthodes. L'outil que j'utilise pour le profilage est callgrind, qui permet de visualiser le résultat du profilage avec une interface graphique, kcachegrind.

Utilisation

Le résultat est assez bordélique, il y a une foule d'informations regroupées dans les onglets, les menus, le graphe, c'est clickable de partout. Mais au moins c'est visuel. On voit clairement ici, par exemple, que le solver Skyline me prend 49% du temps :

Références

Les outils de valgrind, le profilage, kcachegrind.

pgprof

Description

Il semble que ce soit l'équivalent de gprof pour les codes parallélisés avec OpenMP et MPI, avec en plus une interface graphique. Je n'ai pas encore testé.

Références

Site officiel

scalasca

Description

C'est un logiciel open-source pour le profilage de codes parallélisés avec OpenMP et MPI (officiellement Scalable Performance Analysis of Large-Scale Applications), avec interface graphique. Pas encore testé.

Références

Site officiel

cProfile

Description

cProfile est un module Python pour le profilage, utilisé en combinaison avec le module pstats.

Utilisation

Voici un exemple de profilage de la fonction qui charge les modèles dans Metafor:

import cProfile, pstats
cProfile.run('load(\'/home/geoffrey/APC/Calc/Lug/lug3d_8c.py\')', 'profil1')
r1 = pstats.Stats('profil1')
r1.sort_stats('cumulative').print_stats(20)

Le résultat est assez semblable à la sortie de gprof, c'est à dire assez sobre, je dirais presque austère :

Thu Sep  2 17:12:12 2010    profil1

4045151 function calls in 21.459 CPU seconds

Ordered by: cumulative time
List reduced from 237 to 20 due to restriction <20>

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      1    0.000    0.000   21.460   21.460 /home/geoffrey/Metafor/Devel/oo_meta/toolbox/utilities.py:60(load)
      1    0.005    0.005   21.459   21.459 /home/geoffrey/APC/Calc/Lug/lug3d_8c.py:5(<module>)
      1    0.075    0.075   21.243   21.243 /home/geoffrey/Metafor/Devel/oo_meta/toolbox/gmsh.py:26(execute)
      1    3.546    3.546   21.158   21.158 /home/geoffrey/Metafor/Devel/oo_meta/toolbox/gmsh.py:53(__loadMSH)
  94888   14.588    0.000   14.588    0.000 /home/geoffrey/Metafor/Devel/oo_meta/wrap/mtGeo.py:4953(define)
 944646    1.332    0.000    1.332    0.000 /home/geoffrey/Metafor/Devel/oo_meta/wrap/mtGeo.py:2161(__call__)
 106834    0.622    0.000    0.622    0.000 /home/geoffrey/Metafor/Devel/oo_meta/wrap/mtGeo.py:5006(define)
 191666    0.222    0.000    0.222    0.000 /home/geoffrey/Metafor/Devel/oo_meta/wrap/mtGeo.py:1510(addMeshPoint)
 201721    0.216    0.000    0.216    0.000 {method 'split' of 'str' objects}
      1    0.000    0.000    0.184    0.184 /home/geoffrey/Metafor/Devel/oo_meta/wrap/mtViz.py:209(__init__)
      1    0.184    0.184    0.184    0.184 {_mtViz.new_VizWin}
 201726    0.181    0.000    0.181    0.000 {method 'readline' of 'file' objects}
 189780    0.138    0.000    0.138    0.000 {range}
 752976    0.134    0.000    0.134    0.000 {method 'add' of 'set' objects}
1051480    0.126    0.000    0.126    0.000 /home/geoffrey/Metafor/Devel/oo_meta/wrap/mtGeo.py:3418(<lambda>)
 213670    0.034    0.000    0.034    0.000 {method 'append' of 'list' objects}
      1    0.021    0.021    0.021    0.021 /home/geoffrey/Metafor/Devel/oo_meta/wrap/mtViz.py:239(add)
  94893    0.019    0.000    0.019    0.000 {len}
     40    0.000    0.000    0.005    0.000 /home/geoffrey/Metafor/Devel/oo_meta/wrap/__init__.py:81(write)
     40    0.005    0.000    0.005    0.000 /home/geoffrey/Metafor/Devel/oo_meta/wrap/mtViz.py:329(sendStringToCPP)

Références

Doc Python