Il s'agit d'un programme de profilage pour des codes en C/C++.
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.
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.
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 :
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é.
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é.
cProfile est un module Python pour le profilage, utilisé en combinaison avec le module pstats.
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)