2010-12-01 9 views
12

Estoy interesado en la evaluación comparativa de diferentes partes de mi programa para la velocidad. He intentado usar información (estadísticas) y erlang: ahora()ERLANG - Aplicaciones de temporización

Necesito saber hasta el microsegundo cuál es la velocidad media. No sé por qué estoy teniendo problemas con un script que escribí.

Debe ser capaz de comenzar en cualquier lugar y terminar en cualquier lugar. Me encontré con un problema cuando intenté iniciarlo en un proceso que puede estar ejecutándose hasta 4 veces en paralelo.

¿Hay alguien que ya tenga una solución a este problema?

EDIT:

dispuesto a dar una recompensa si alguien puede proporcionar un script para hacerlo. NECESITA PARA SPAWN aunque proceso múltiple '. No puedo aceptar una función como temporizador ... al menos en las implementaciones que he visto. IT solo atraviesa un proceso e incluso entonces es necesaria una edición importante para una prueba completa de un programa completo. Espero haberlo dejado suficientemente claro.

+0

hay un par de ungivens: ¿Es esta una ¿sistema de producción? 'eprof' y * especialmente *' fprof' incurren en un golpe de rendimiento cuando se ejecutan. Ambos pueden seguir procesos recién engendrados. Sin embargo, es posible que desee medir algo más, como viajes redondos de ida y vuelta, etc. La forma más fácil es, probablemente, inyectar una llamada 'timer: tc' alrededor de la función que se va a medir. Alternativamente, tome 'erlang: now()' y envíelo a otro proceso que luego puede hacer el trabajo de medición. –

+0

tiene su script eprof (o tutorial) más abajo en la página :) –

Respuesta

38

Aquí es cómo utilizar eprof, probablemente la solución más fácil para usted:

primer lugar usted necesita para iniciarlo, como la mayoría de las aplicaciones por ahí:

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

Eprof es compatible con el modo de dos perfiles. Puedes llamarlo y pedirle que muestre una determinada función, pero no podemos usar eso porque otros procesos lo estropearán todo. Necesitamos iniciarlo manualmente y dígale cuándo detenerse (es por eso que no tendrá un script fácil, por cierto).

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

Esto le dice a eprof que haga un perfil de todo lo que se ejecutará y generará desde el shell. Nuevos procesos serán incluidos aquí. Voy a correr alguna función arbitraria de multiprocesamiento que tengo, que genera cerca de 4 procesos se comunican entre sí por unos segundos:

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> ... 

Ahora puedo decir eprof para detener la función de perfiles de una vez ha terminado de correr.

26> eprof:stop_profiling(). 
profiling_stopped 

Y queremos los registros. Eprof los imprimirá en la pantalla por defecto. Puede solicitar que también inicie sesión en un archivo con eprof:log(File). Entonces puedes decirle que analice los resultados. Le decimos que para contraer el tiempo de ejecución de todos los procesos en una sola tabla con la opción total (ver el manual para más opciones):

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] 

y se puede ver que la mayoría de las veces (50%) se gasta en dict: store/3. 16.67% se toma al generar el resultado, otro 16.67% es tomado por erl_eval (esta es la razón por la que obtienes ejecutando funciones cortas en el intérprete de comandos - analizarlas se vuelve más largo que ejecutarlas).

A continuación, puede comenzar a partir de allí. Esa es la base de los tiempos de generación de perfiles con Erlang. Maneje con cuidado, eprof puede ser una gran carga en un sistema de producción o para funciones que se ejecutan por mucho tiempo. Especialmente en un sistema de producción.

+0

Nice Work man, lo probé, se ve bien .. Una pregunta: ¿Por qué algunos procesos 'dicen 0 llamadas en mi prog? Sé que tuvo que haber sido llamado para tener otras funciones, como listas: llamar a flatten. ¿Es esto algo obvio? O un poco más esotérico para mi prog. – BAR

+0

No podría decir sin el código: no recuerdo haberlo visto en mi propio código. –

3

La forma normal de hacerlo es con el temporizador: tc. Here es una buena explicación.

+0

Lo necesito para ejecutar el proceso 'no solo para probar uno. – BAR

+1

'eprof' es la herramienta que desea. –

0

que se puede recomendar esta herramienta: https://github.com/virtan/eep

Obtendrá algo como esto https://raw.github.com/virtan/eep/master/doc/sshot1.png como resultado.

instrucciones paso a paso para crear perfiles de todos los procesos en el sistema que ejecuta:

El sistema de destino:

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

En el escritorio:

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