2010-12-01 10 views
12

Je suis intéressé par l'analyse comparative de différentes parties de mon programme pour la vitesse. J'ai essayé d'utiliser info (statistiques) et erlang: maintenant()ERLANG - Applications de temporisation

J'ai besoin de savoir jusqu'à la microseconde quelle est la vitesse moyenne. Je ne sais pas pourquoi j'ai un problème avec un script que j'ai écrit.

Il devrait pouvoir commencer n'importe où et finir n'importe où. J'ai rencontré un problème lorsque j'ai essayé de le démarrer sur un processus qui peut fonctionner jusqu'à 4 fois en parallèle.

Y a-t-il quelqu'un qui a déjà une solution à ce problème?

EDIT:

Je donne une prime si quelqu'un peut fournir un script pour le faire. IL A BESOIN DE SPAWN bien que plusieurs processus '. Je ne peux pas accepter une fonction comme timer ... au moins dans les implémentations que j'ai vues. L'informatique ne traverse qu'un seul processus et même dans ce cas, une édition majeure est nécessaire pour un test complet d'un programme complet. J'espère que je l'ai fait assez clair.

+0

Il y a quelques ungivens: Est-ce un Système de production? 'eprof' et * surtout *' fprof' encourent une baisse de performance lors de l'exécution. Les deux peuvent suivre des procèses nouvellement engendrées. Vous pouvez vouloir mesurer quelque chose d'autre comme des allers-retours de réseau et ainsi de suite cependant! Le plus simple est probablement d'injecter un appel 'timer: tc' autour de la fonction à mesurer. Sinon, prenez le 'erlang: now()' et envoyez-le à un autre processus qui peut ensuite effectuer le travail de mesure. –

+0

vous avez votre script eprof (ou une procédure pas à pas) plus bas sur la page :) –

Répondre

38

Voici comment utiliser eprof, probablement la meilleure solution pour vous:

Vous devez d'abord commencer, comme la plupart des applications là-bas:

23> eprof:start(). 
{ok,<0.95.0>} 

Eprof prend en charge deux modes de profilage. Vous pouvez l'appeler et demander de profiler une certaine fonction, mais nous ne pouvons pas l'utiliser parce que d'autres processus vont tout gâcher. Nous devons commencer manuellement le profilage et lui dire quand arrêter (c'est pourquoi vous n'aurez pas de script facile, d'ailleurs).

24> eprof:start_profiling([self()]). 
profiling 

Cela dit à eprof de profiler tout ce qui sera exécuté et engendré à partir du shell. De nouveaux processus seront inclus ici. Je courrai une fonction de multitraitement arbitraire je, qui engendre environ 4 processus communiquant entre eux pendant quelques secondes:

25> trade_calls:main_ab(). 
Spawned Carl: <0.99.0> 
Spawned Jim: <0.101.0> 
<0.100.0> 
Jim: asking user <0.99.0> for a trade 
Carl: <0.101.0> asked for a trade negotiation 
Carl: accepting negotiation 
Jim: starting negotiation 
... <snip> ... 

Nous pouvons maintenant dire eprof d'arrêter le profilage une fois que la fonction est fait en cours d'exécution.

26> eprof:stop_profiling(). 
profiling_stopped 

Et nous voulons les journaux. Eprof les imprime à l'écran par défaut. Vous pouvez demander à ce qu'il soit également enregistré dans un fichier avec eprof:log(File). Ensuite, vous pouvez le dire pour analyser les résultats. Nous disons à réduire le temps d'exécution de tous les processus en une seule table avec l'option total (voir le manual pour plus d'options):

27> eprof:analyze(total).   
FUNCTION         CALLS  % TIME [uS/CALLS] 
--------         ----- --- ---- [----------] 
io:o_request/3        46 0.00  0 [  0.00] 
io:columns/0         2 0.00  0 [  0.00] 
io:columns/1         2 0.00  0 [  0.00] 
io:format/1         4 0.00  0 [  0.00] 
io:format/2         46 0.00  0 [  0.00] 
io:request/2         48 0.00  0 [  0.00] 
... 
erlang:atom_to_list/1       5 0.00  0 [  0.00] 
io:format/3         46 16.67 1000 [  21.74] 
erl_eval:bindings/1       4 16.67 1000 [ 250.00] 
dict:store_bkt_val/3      400 16.67 1000 [  2.50] 
dict:store/3        114 50.00 3000 [  26.32] 

Et vous pouvez voir que la plupart du temps (50%) est passé dans dict: store/3. 16.67% est pris en sortie du résultat, un autre 16.67% est pris par erl_eval (c'est pourquoi vous obtenez en exécutant des fonctions courtes dans le shell - les analyser devient plus long que les exécuter).

Vous pouvez alors commencer à partir de là. Voilà les bases du profilage des temps d'exécution avec Erlang. Manipuler avec soin, eprof peut être assez chargé sur un système de production ou pour des fonctions qui durent trop longtemps. Surtout sur un système de production.

+0

Nice Work man, essayé, regarde bien .. Une question: Pourquoi certains processus 'disent 0 appels dans mon prog? Je sais que cela a dû être appelé afin d'avoir d'autres funs comme des listes: aplatissez-vous. Est-ce quelque chose d'évident? Ou un peu plus ésotérique à mon prog. – BAR

+0

Je ne pourrais pas dire sans le code - je ne me souviens pas l'avoir vu dans mon propre code. –

3

La méthode normale consiste à utiliser timer: tc. Here est une bonne explication.

+0

Je dois le faire pour traverser le processus et pas seulement pour le tester. – BAR

+1

'eprof' est l'outil que vous voulez. –

0

Je peux vous recommander cet outil: https://github.com/virtan/eep

Vous obtiendrez quelque chose comme ça https://raw.github.com/virtan/eep/master/doc/sshot1.png en conséquence.

Instructions étape par étape pour le profilage de tous les processus sur le système en cours d'exécution:

sur le système cible:

1> eep:start_file_tracing("file_name"), timer:sleep(20000), eep:stop_tracing(). 
$ scp -C $PWD/file_name.trace desktop: 

Sur le bureau:

1> eep:convert_tracing("file_name"). 
$ kcachegrind callgrind.out.file_name