Alternatives à gprof [fermé]

166

Quels autres programmes font la même chose que gprof?

neuromancien
la source
2
quelles plateformes vous intéressent?
osgx
2
Je m'intéresse à Linux.
neuromancer
2
duplication possible de stackoverflow.com/questions/375913/…
Dour High Arch
13
@Gregory - Je suis enclin à être d'accord, et peut-être qu'il devrait contribuer avec ses propres réponses, 229 contre 6, toutes les 6 réponses étant à ses propres questions ...
Jean-Bernard Pellerin
5
Comment cette question peut-elle ne pas être constructive?
JohnTortugo

Réponses:

73

Valgrind a un profileur de comptage d'instructions avec un très bon visualiseur appelé KCacheGrind . Comme le recommande Mike Dunlavey, Valgrind compte la fraction d'instructions pour laquelle une procédure est active sur la pile, même si je suis désolé de dire qu'elle semble devenir confuse en présence d'une récursivité mutuelle. Mais le visualiseur est très agréable et à des années-lumière d'avance gprof.

Norman Ramsey
la source
2
@Norman: ++ Cette confusion sur la récursivité semble endémique aux systèmes qui ont le concept de temps de propagation entre les nœuds d'un graphe. Je pense également que l'heure de l'horloge murale est généralement plus utile que les heures d'instruction du processeur, et les lignes de code (instructions d'appel) sont plus utiles que les procédures. Si des échantillons de pile à des heures d'horloge murale aléatoires sont prélevés, le coût fractionnaire d'une ligne (ou d'une procédure, ou de toute autre description que vous pouvez faire) est simplement estimé par la fraction d'échantillons qui le présente.
Mike Dunlavey
1
... Je mets l'accent sur les instructions d'appel, mais cela s'applique à toutes les instructions. Si l'on a un goulot d'étranglement de point chaud honnête à bonté, comme une sorte de bulle d'un grand tableau de nombres, alors les instructions de comparaison / saut / échange / incrémentation de la boucle interne seront en haut / en bas de presque tous les échantillons de pile. . Mais (d'autant plus que le logiciel prend de l'ampleur et que pratiquement aucune routine n'a beaucoup de temps pour "soi"), de nombreux problèmes sont en fait des instructions d'appel, demandant un travail qui, quand il est clair combien il coûte, n'a pas vraiment à être fait.
Mike Dunlavey
3
... Regarde ça. Je pense qu'ils sont presque sur la bonne voie: rotateright.com/zoom.html
Mike Dunlavey
195

gprof (lire l'article) existe pour des raisons historiques. Si vous pensez que cela vous aidera à trouver des problèmes de performances, cela n'a jamais été annoncé comme tel. Voici ce que dit le journal:

Le profil peut être utilisé pour comparer et évaluer les coûts de diverses implémentations.

Il ne dit pas qu'il peut être utilisé pour identifier les différentes implémentations à évaluer, bien que cela implique qu'il pourrait, dans des circonstances particulières:

surtout si de petites portions du programme dominent son temps d'exécution.

Qu'en est-il des problèmes qui ne sont pas si localisés? Cela n'a-t-il pas d'importance? Ne placez pas d'attentes sur gprof qui n'ont jamais été réclamées pour cela. Ce n'est qu'un outil de mesure et uniquement des opérations liées au processeur.

Essayez plutôt ceci.
Voici un exemple d'accélération 44x.
Voici une accélération 730x.
Voici une démonstration vidéo de 8 minutes.
Voici une explication des statistiques.
Voici une réponse aux critiques.

Il y a une simple observation sur les programmes. Dans une exécution donnée, chaque instruction est responsable d'une fraction du temps global (en particulier les callinstructions), en ce sens que si elle n'était pas là, le temps ne serait pas dépensé. Pendant ce temps, l'instruction est sur la pile **. Quand cela est compris, vous pouvez voir que -

gprof incarne certains mythes sur la performance, tels que:

  1. cet échantillonnage du compteur de programme est utile.
    Cela n'est utile que si vous avez un goulot d'étranglement inutile, tel qu'une sorte de bulle d'un grand tableau de valeurs scalaires. Dès que vous, par exemple, le changez en un tri utilisant la comparaison de chaînes, il s'agit toujours d'un goulot d'étranglement, mais l'échantillonnage du compteur de programme ne le verra pas car maintenant le hotspot est en comparaison de chaînes. D'autre part, s'il devait échantillonner le compteur de programme étendu (la pile d'appels), le point auquel la comparaison de chaînes est appelée, la boucle de tri, est clairement affiché. En fait, gprof était une tentative de remédier aux limites de l'échantillonnage sur ordinateur uniquement.

  2. que les fonctions de chronométrage sont plus importantes que la capture de lignes de code chronophages.
    La raison de ce mythe est que gprof n'était pas capable de capturer des échantillons de pile, donc à la place, il chronomètre les fonctions, compte leurs invocations et essaie de capturer le graphe d'appel. Cependant, une fois qu'une fonction coûteuse est identifiée, vous devez toujours rechercher à l'intérieur les lignes qui sont responsables du temps. S'il y avait des échantillons de pile que vous n'auriez pas besoin de regarder, ces lignes seraient sur les échantillons. (Une fonction typique peut avoir 100 à 1000 instructions. Un appel de fonction est une instruction, donc quelque chose qui localise les appels coûteux est de 2 à 3 ordres de grandeur plus précis.)

  3. que le graphe d'appel est important.
    Ce que vous devez savoir sur un programme n'est pas l' endroit où il passe son temps, mais pourquoi. Lorsqu'il passe du temps dans une fonction, chaque ligne de code de la pile donne un lien dans la chaîne de raisonnement expliquant pourquoi elle est là. Si vous ne pouvez voir qu'une partie de la pile, vous ne pouvez voir qu'une partie de la raison, vous ne pouvez donc pas dire avec certitude si ce temps est réellement nécessaire. Que vous dit le graphe d'appel? Chaque arc vous indique qu'une fonction A était en train d'appeler une fonction B pendant une certaine fraction du temps. Même si A n'a qu'une seule ligne de code appelant B, cette ligne ne donne qu'une petite partie de la raison. Si vous êtes assez chanceux, peut-être que cette ligne a une mauvaise raison. Habituellement, vous devez voir plusieurs lignes simultanées pour trouver une mauvaise raison si elle est là. Si A appelle B à plus d'un endroit, il vous en dit encore moins.

  4. cette récursivité est un problème délicat et déroutant.
    C'est uniquement parce que gprof et d'autres profileurs perçoivent le besoin de générer un graphe d'appel, puis d'attribuer des heures aux nœuds. Si l'on a des échantillons de la pile, le coût en temps de chaque ligne de code qui apparaît sur les échantillons est un nombre très simple - la fraction d'échantillons sur laquelle elle se trouve. S'il y a récursivité, une ligne donnée peut apparaître plusieurs fois sur un échantillon. Peu importe. Supposons que des échantillons soient prélevés toutes les N ms et que la ligne apparaisse sur F% d'entre eux (seuls ou non). Si cette ligne peut prendre peu de temps (par exemple en la supprimant ou en la branchant autour d'elle), alors ces échantillons disparaîtraient et le temps serait réduit de F%.

  5. cette précision de la mesure du temps (et donc d'un grand nombre d'échantillons) est importante.
    Réfléchis-y une seconde. Si une ligne de code est sur 3 échantillons sur cinq, alors si vous pouviez la tirer comme une ampoule, c'est environ 60% de temps en moins qui serait utilisé. Maintenant, vous savez que si vous aviez prélevé 5 échantillons différents, vous ne l'auriez peut-être vu que 2 fois, ou jusqu'à 4. Ainsi, la mesure à 60% ressemble plus à une plage générale de 40% à 80%. Si ce n'était que de 40%, diriez-vous que le problème ne vaut pas la peine d'être réglé? Alors, quel est le point de précision du temps, quand ce que vous voulez vraiment est de trouver les problèmes ? 500 ou 5000 échantillons auraient mesuré le problème avec une plus grande précision, mais ne l'auraient pas trouvé avec plus de précision.

  6. que le comptage des appels d'instructions ou de fonctions est utile.
    Supposons que vous sachiez qu'une fonction a été appelée 1000 fois. Pouvez-vous dire à partir de là quelle fraction de temps cela coûte? Vous devez également savoir combien de temps il faut pour s'exécuter, en moyenne, multipliez-le par le nombre et divisez par le temps total. Le temps moyen d'appel peut varier de nanosecondes à secondes, de sorte que le décompte à lui seul ne dit pas grand-chose. S'il y a des échantillons de pile, le coût d'une routine ou d'une instruction n'est que la fraction d'échantillons sur laquelle elle se trouve. Cette fraction de temps est ce qui pourrait en principe être globalement économisé si la routine ou la déclaration pouvait être faite pour ne pas prendre de temps, c'est donc ce qui a la relation la plus directe avec la performance.

  7. que les échantillons n'ont pas besoin d'être prélevés lorsqu'ils sont bloqués
    Les raisons de ce mythe sont doubles: 1) que l'échantillonnage PC n'a pas de sens lorsque le programme est en attente, et 2) la préoccupation de l'exactitude du timing. Cependant, pour (1), le programme peut très bien attendre quelque chose qu'il a demandé, comme des E / S de fichier, que vous devez connaître et quels échantillons de pile révèlent. (De toute évidence, vous voulez exclure les échantillons en attendant l'entrée de l'utilisateur.) Pour (2) si le programme attend simplement à cause de la concurrence avec d'autres processus, cela se produit probablement de manière assez aléatoire pendant son exécution. Ainsi, bien que le programme prenne plus de temps, cela n'aura pas un effet important sur la statistique qui compte, le pourcentage de temps pendant lequel les instructions sont sur la pile.

  8. que le "temps propre" compte Le
    temps propre n'a de sens que si vous mesurez au niveau de la fonction, pas au niveau de la ligne, et vous pensez avoir besoin d'aide pour discerner si le temps de la fonction entre dans le calcul purement local par rapport aux routines appelées. Si vous récapitulez au niveau de la ligne, une ligne représente le temps propre si elle se trouve à la fin de la pile, sinon elle représente le temps inclusif. Quoi qu'il en soit, ce qu'il en coûte, c'est le pourcentage d'échantillons de pile sur lesquels il se trouve, ce qui le localise pour vous dans les deux cas.

  9. que les échantillons doivent être prélevés à haute fréquence
    Cela vient de l'idée qu'un problème de performance peut être rapide et que les échantillons doivent être fréquents pour y parvenir. Mais, si le problème coûte 20%, par exemple, sur un temps de fonctionnement total de 10 secondes (ou autre), alors chaque échantillon de ce temps total aura 20% de chances de le toucher, peu importe si le problème se produit. dans un seul morceau comme celui-ci
    .....XXXXXXXX...........................
    .^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^(20 échantillons, 4 hits)
    ou dans de nombreux petits morceaux comme celui-ci
    X...X...X.X..X.........X.....X....X.....
    .^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^.^(20 échantillons, 3 hits) Dans tous les
    cas, le nombre de hits sera en moyenne d'environ 1 sur 5, quel que soit le nombre d'échantillons prélevés, ou combien peu. (Moyenne = 20 * 0,2 = 4. Écart type = +/- sqrt (20 * 0,2 * 0,8) = 1,8.)

  10. que vous essayez de trouver le goulot
    d' étranglement comme s'il n'y en avait qu'un. Considérez le calendrier d'exécution suivant: vxvWvzvWvxvWvYvWvxvWv.vWvxvWvYvW
    Il consiste en un véritable travail utile, représenté par .. Il y a des problèmes de performances vWxYzprenant respectivement 1/2, 1/4, 1/8, 1/16, 1/32 du temps. L'échantillonnage trouve vfacilement. Il est supprimé, laissant
    xWzWxWYWxW.WxWYW
    maintenant le programme prend deux fois moins de temps à exécuter, et Wprend maintenant la moitié du temps, et se trouve facilement. Il est supprimé, laissant
    xzxYx.xY
    Ce processus se poursuit, chaque fois en supprimant le plus gros problème de performances, en pourcentage, jusqu'à ce que rien à supprimer ne puisse être trouvé. Maintenant, la seule chose exécutée est ., qui s'exécute dans 1/32 du temps utilisé par le programme d'origine. C'est l' effet de grossissement, par lequel la suppression de tout problème augmente le reste, en pourcentage, car le dénominateur est réduit.
    Un autre point crucial est que chaque problème doit être trouvé - ne manque aucun des 5. Tout problème non trouvé et corrigé réduit considérablement le taux d'accélération final. Le simple fait d'en trouver, mais pas tous, n'est pas «suffisant».

AJOUTÉ: Je voudrais juste souligner une des raisons pour lesquelles gprof est populaire - il est enseigné, probablement parce qu'il est gratuit, facile à enseigner et qu'il existe depuis longtemps. Une recherche rapide sur Google localise certaines institutions académiques qui l'enseignent (ou semblent le faire):

berkeley bu clemson colorado duc earlham fsu indiana mit msu ncsa.illinois ncsu nyu ou princeton psu stanford ucsd umd umich utah utexas utk wustl

** À l'exception des autres façons de demander du travail à faire, qui ne laissent aucune trace indiquant pourquoi , comme par l'envoi de messages.

Mike Dunlavey
la source
3
@Norman: J'ai créé un profileur sur cette base, en C pour DOS, vers 93. Je l'ai appelé encore un autre analyseur de performances, et je l'ai fait une démonstration lors de réunions IEEE, mais c'est tout ce que j'ai fait. Il existe un produit de RotateRight appelé Zoom qui n'est pas trop éloigné. Sur * nix, pstack est bon pour le faire manuellement. Ma liste de choses à faire pour le travail (pharmacométrie sous Windows) est d'environ un mile de long, ce qui exclut les projets amusants, sans parler de la famille. Cela pourrait être utile: stackoverflow.com/questions/1777669/…
Mike Dunlavey
6
J'ai toujours trouvé les profileurs pas si utiles pour corriger le code lent, et à la place, j'ai utilisé des bits sélectifs de code de débogage pour mesurer le temps pris par un groupe d'instructions de mon choix, souvent aidé par de petites macros triviales ou autre. Il ne m'a jamais fallu trop de temps pour trouver le coupable, mais j'ai toujours été gêné par mon approche "peaux d'ours et couteaux en pierre" quand "tout le monde" (pour autant que je sache) utilise les outils sophistiqués. Merci de m'avoir montré pourquoi je n'ai jamais pu obtenir les informations dont j'avais besoin du profileur. C'est l'une des idées les plus importantes que j'ai vues sur SO. Bien joué!
Wayne Conrad
7
@osgx: Je ne veux rien déchirer. C'est comme une vieille voiture préférée, simple et robuste, mais il y a des choses qu'elle ne fait pas, et nous devons en être conscients, et pas seulement, nous devons nous réveiller des mythes. J'apprécie que sur certaines plates-formes, il peut être difficile d'obtenir des échantillons de pile, mais si un problème est tel que gprof ne le trouve pas, le fait que ce soit le seul outil est un petit confort.
Mike Dunlavey
2
@Andrew: ... et si cette raison s'applique à une fraction significative d'échantillons (comme plus d'un), alors la ou les lignes de code qui pourraient éliminer cette activité se trouvent sur ces échantillons. Un graphique peut vous en donner une idée , mais un nombre limité d'échantillons de pile vous les montrera simplement.
Mike Dunlavey
2
@Matt: Exemples de problèmes de performances d'E / S trouvés de cette façon: 1) impression des messages du journal dans un fichier ou la console, ce qui a été considéré à tort comme insignifiant. 2) Conversion entre texte et double en IO numérique. 3) Les E / S souterraines extrayant des chaînes internationalisées au démarrage, les chaînes qui, en fait, n'avaient pas besoin d'être internationalisées. J'ai trouvé de nombreux exemples comme ceux-ci.
Mike Dunlavey le
63

Comme je n'ai rien vu ici sur perfun outil relativement nouveau de profilage du noyau et des applications utilisateur sous Linux, j'ai décidé d'ajouter ces informations.

Tout d'abord - ceci est un tutoriel sur le profilage Linux avecperf

Vous pouvez utiliser perfsi votre noyau Linux est supérieur à 2.6.32 ou oprofiles'il est plus ancien. Les deux programmes ne nécessitent pas de votre part d'instrumenter votre programme (comme le gprofrequiert). Cependant, pour obtenir correctement le graphe d'appel, perfvous devez créer votre programme avec -fno-omit-frame-pointer. Par exemple: g++ -fno-omit-frame-pointer -O2 main.cpp.

Vous pouvez voir l'analyse "en direct" de votre application avec perf top:

sudo perf top -p `pidof a.out` -K

Ou vous pouvez enregistrer les données de performance d'une application en cours d'exécution et les analyser après cela:

1) Pour enregistrer les données de performance:

perf record -p `pidof a.out`

ou pour enregistrer pendant 10 secondes:

perf record -p `pidof a.out` sleep 10

ou pour enregistrer avec call graph ()

perf record -g -p `pidof a.out` 

2) Pour analyser les données enregistrées

perf report --stdio
perf report --stdio --sort=dso -g none
perf report --stdio -g none
perf report --stdio -g

Ou vous pouvez enregistrer les données de performance d'une application et les analyser ensuite simplement en lançant l'application de cette manière et en attendant qu'elle se termine:

perf record ./a.out

Ceci est un exemple de profilage d'un programme de test

Le programme de test est dans le fichier main.cpp (je mettrai main.cpp en bas du message):

Je le compile de cette manière:

g++ -m64 -fno-omit-frame-pointer -g main.cpp -L.  -ltcmalloc_minimal -o my_test

J'utilise libmalloc_minimial.socar il est compilé avec -fno-omit-frame-pointertandis que la libc malloc semble être compilée sans cette option. Ensuite, je lance mon programme de test

./my_test 100000000 

Ensuite, j'enregistre les données de performance d'un processus en cours:

perf record -g  -p `pidof my_test` -o ./my_test.perf.data sleep 30

Ensuite, j'analyse la charge par module:

rapport de perf --stdio -g aucun --sort comm, dso -i ./my_test.perf.data

# Overhead  Command                 Shared Object
# ........  .......  ............................
#
    70.06%  my_test  my_test
    28.33%  my_test  libtcmalloc_minimal.so.0.1.0
     1.61%  my_test  [kernel.kallsyms]

Ensuite, la charge par fonction est analysée:

rapport de perf --stdio -g aucun -i ./my_test.perf.data | c ++ filt

# Overhead  Command                 Shared Object                       Symbol
# ........  .......  ............................  ...........................
#
    29.30%  my_test  my_test                       [.] f2(long)
    29.14%  my_test  my_test                       [.] f1(long)
    15.17%  my_test  libtcmalloc_minimal.so.0.1.0  [.] operator new(unsigned long)
    13.16%  my_test  libtcmalloc_minimal.so.0.1.0  [.] operator delete(void*)
     9.44%  my_test  my_test                       [.] process_request(long)
     1.01%  my_test  my_test                       [.] operator delete(void*)@plt
     0.97%  my_test  my_test                       [.] operator new(unsigned long)@plt
     0.20%  my_test  my_test                       [.] main
     0.19%  my_test  [kernel.kallsyms]             [k] apic_timer_interrupt
     0.16%  my_test  [kernel.kallsyms]             [k] _spin_lock
     0.13%  my_test  [kernel.kallsyms]             [k] native_write_msr_safe

     and so on ...

Ensuite, les chaînes d'appels sont analysées:

rapport perf --stdio -g graph -i ./my_test.perf.data | c ++ filt

# Overhead  Command                 Shared Object                       Symbol
# ........  .......  ............................  ...........................
#
    29.30%  my_test  my_test                       [.] f2(long)
            |
            --- f2(long)
               |
                --29.01%-- process_request(long)
                          main
                          __libc_start_main

    29.14%  my_test  my_test                       [.] f1(long)
            |
            --- f1(long)
               |
               |--15.05%-- process_request(long)
               |          main
               |          __libc_start_main
               |
                --13.79%-- f2(long)
                          process_request(long)
                          main
                          __libc_start_main

    15.17%  my_test  libtcmalloc_minimal.so.0.1.0  [.] operator new(unsigned long)
            |
            --- operator new(unsigned long)
               |
               |--11.44%-- f1(long)
               |          |
               |          |--5.75%-- process_request(long)
               |          |          main
               |          |          __libc_start_main
               |          |
               |           --5.69%-- f2(long)
               |                     process_request(long)
               |                     main
               |                     __libc_start_main
               |
                --3.01%-- process_request(long)
                          main
                          __libc_start_main

    13.16%  my_test  libtcmalloc_minimal.so.0.1.0  [.] operator delete(void*)
            |
            --- operator delete(void*)
               |
               |--9.13%-- f1(long)
               |          |
               |          |--4.63%-- f2(long)
               |          |          process_request(long)
               |          |          main
               |          |          __libc_start_main
               |          |
               |           --4.51%-- process_request(long)
               |                     main
               |                     __libc_start_main
               |
               |--3.05%-- process_request(long)
               |          main
               |          __libc_start_main
               |
                --0.80%-- f2(long)
                          process_request(long)
                          main
                          __libc_start_main

     9.44%  my_test  my_test                       [.] process_request(long)
            |
            --- process_request(long)
               |
                --9.39%-- main
                          __libc_start_main

     1.01%  my_test  my_test                       [.] operator delete(void*)@plt
            |
            --- operator delete(void*)@plt

     0.97%  my_test  my_test                       [.] operator new(unsigned long)@plt
            |
            --- operator new(unsigned long)@plt

     0.20%  my_test  my_test                       [.] main
     0.19%  my_test  [kernel.kallsyms]             [k] apic_timer_interrupt
     0.16%  my_test  [kernel.kallsyms]             [k] _spin_lock
     and so on ...

Donc, à ce stade, vous savez où votre programme passe du temps.

Et voici main.cpp pour le test:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

time_t f1(time_t time_value)
{
  for (int j =0; j < 10; ++j) {
    ++time_value;
    if (j%5 == 0) {
      double *p = new double;
      delete p;
    }
  }
  return time_value;
}

time_t f2(time_t time_value)
{
  for (int j =0; j < 40; ++j) {
    ++time_value;
  }
  time_value=f1(time_value);
  return time_value;
}

time_t process_request(time_t time_value)
{

  for (int j =0; j < 10; ++j) {
    int *p = new int;
    delete p;
    for (int m =0; m < 10; ++m) {
      ++time_value;
    }
  }
  for (int i =0; i < 10; ++i) {
    time_value=f1(time_value);
    time_value=f2(time_value);
  }
  return time_value;
}

int main(int argc, char* argv2[])
{
  int number_loops = argc > 1 ? atoi(argv2[1]) : 1;
  time_t time_value = time(0);
  printf("number loops %d\n", number_loops);
  printf("time_value: %d\n", time_value );

  for (int i =0; i < number_loops; ++i) {
    time_value = process_request(time_value);
  }
  printf("time_value: %ld\n", time_value );
  return 0;
}
osgx
la source
J'ai juste exécuté votre exemple et pris 5 stackshots. Voici ce qu'ils ont trouvé: 40% (environ) du temps f1appelait delete. 40% (environ) du temps process_requestappelait delete. Une bonne partie du reste a été dépensée new. Les mesures sont approximatives, mais les points chauds sont localisés.
Mike Dunlavey
Qu'est-ce qu'un stackshot? Est-ce que ce sont les pstacksorties?
2
As in my answer, you run it under a debugger and hit ^C at a random time and capture the stack trace. 1) Je pense que votre technique n'est pas utile lorsque vous devez analyser des problèmes de performances pour un programme fonctionnant sur le serveur de votre client. 2) Je ne sais pas comment vous appliquez cette technique pour obtenir des informations sur un programme comportant de nombreux threads qui traitent différentes requêtes. Je veux dire quand l'image générale est assez compliquée.
2
Quant au n ° 1. Parfois, les clients appellent et disent que votre programme fonctionne lentement. Vous ne pouvez pas dire ça immédiatement the problem is outside your code, n'est-ce pas? Puisque vous pourriez avoir besoin de quelques informations pour soutenir votre point. Dans cette situation, vous devrez peut-être à un moment donné profiler votre application. Vous ne pouvez pas simplement demander à votre client de démarrer gdb et d'appuyer sur ^ C et d'obtenir des piles d'appels. C'était mon point. Ceci est un exemple spielwiese.fontein.de/2012/01/22/… . J'ai eu ce problème et le profilage m'a beaucoup aidé.
2
Quant au n ° 2. Simplifier est une bonne approche, je suis d'accord. Parfois ça marche. Si un problème de performances se produit uniquement sur le serveur d'un client et que vous ne pouvez pas les reproduire sur votre serveur, les profils sont utiles.
21

Essayez OProfile . C'est un bien meilleur outil pour profiler votre code. Je suggérerais également Intel VTune .

Les deux outils ci-dessus peuvent réduire le temps passé dans une ligne de code particulière, annoter votre code, afficher l'assemblage et la quantité d'instruction particulière nécessaire. En plus de la métrique de temps, vous pouvez également interroger des compteurs spécifiques, c'est-à-dire des hits de cache, etc.

Contrairement à gprof, vous pouvez profiler n'importe quel processus / binaire en cours d'exécution sur votre système en utilisant l'un des deux.

Anycorn
la source
2
Comme mentionné également dans la réponse valgrind, Zoom de RotateRight ( rotateright.com ) fournit une interface beaucoup plus agréable et permet le profilage à distance.
JanePhanie
n'a pas aimé oprofile, il semblait aléatoire
Matt Joiner
@Matt un point particulier?
Anycorn le
Il n'a pas pu faire face à plus de 10 secondes d'exécution avant de générer des débordements de statistiques, la sortie n'était pas particulièrement utile et la documentation est affreuse.
Matt Joiner
1
@Tho OProfile: ARM, POWER, ia64, ...
Anycorn
8

Jetez un œil à Sysprof .

Votre distribution l'a peut-être déjà.

Søren Sandmann
la source
sysprof a généré une sortie assez inutile et difficile à lire
Matt Joiner