2010-11-22 56 views
2

Je fais une programmation intensive d'entrée/sortie en C sur GNU/Linux et j'aimerais pouvoir tracer tous les appels d'E/S et connaître les minutages que l'application passe dormir, attendre IO pour chaque appelOutil pour tracer les horaires des appels système io

En dehors de la méthode DIY utilisant gettimeoftheday partout, y a-t-il un outil pour cela? Je veux être capable de distinguer les appels les uns des autres.

Ex d'une sortie qui serait utile:

 
sendto at myprog.c:42 : 30µs 
recvfrom at myprog.c:48 : 45µs 
... 

Note: ce que je veux est en temps réel, pas le temps cpu comme profileurs donnent généralement.

Merci

+0

Quel système d'exploitation? Par exemple. Mac OS X a "Instruments" qui fait ce genre de chose. –

+0

Un peu hors sujet, mais juste au cas où cela devient un résultat élevé dans google. Pour faire exactement cela dans 'python', vous pouvez consulter cet outil http://mg.pov.lt/blog/you-gotta-love-profiling.html – Falmarri

Répondre

3

La commande strace a l'option -T qui devrait faire ce que vous avez besoin. J'ai vérifié le code source, il appelle gettimeofday (2) pour obtenir l'heure, donc il fait rapport sur l'heure de l'horloge murale, pas le temps CPU.

Exemple de sortie de strace -p 2956 -T sur mon ordinateur:

stat("/proc/sys/fs/binfmt_misc", {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0 <0.000028> 
stat("/media/Klatch", {st_mode=S_IFDIR|0711, st_size=4096, ...}) = 0 <0.000021> 
stat("/media/Drum", {st_mode=S_IFDIR|0711, st_size=4096, ...}) = 0 <0.000021> 
close(18)        = 0 <0.000019> 
munmap(0x7fa088e60000, 4096)   = 0 <0.000022> 
open("/etc/mtab", O_RDONLY)    = 18 <0.000024> 
fstat(18, {st_mode=S_IFREG|0644, st_size=742, ...}) = 0 <0.000015> 

Le temps est à la fin de la ligne, en quelques secondes. C'est 15 à 28 microsecondes pour les appels système dans l'exemple ci-dessus.

+0

Regardez de plus près les options de synchronisation que strace vous offre. Il y a des modes de temporisation absolus, relatifs et cumulatifs. Ils ont tous de bons usages. – Marcin

+0

Ok, c'est plutôt bien, dommage qu'il ne puisse pas utiliser les symboles de débogage aussi pour indiquer de quelle ligne du code source vient l'appel. –

+1

@Jocelyn: strace '-i' option combinée avec' addr2line -fe' devrait prendre soin de cela. – ninjalj

0

Il y a un couteau suisse que, pour une raison étrange, tout le monde ne sait pas, peut-être parce que c'est trop simple (et aussi moche). Exécutez-le sous GDB et just pause it plusieurs fois, comme 10. À chaque fois, étudiez la pile d'appels. Si 50% du temps est en E/S, 50% +/- des échantillons le montreront dans les E/S, et chaque ligne de code sur la pile d'appels montrera une partie de la chaîne de pourquoi ça fait l'E/S. Idem pour le sommeil ou tout autre appel bloquant. Si le temps n'est pas bloqué, comme si vous étiez en train de trier un énorme tableau, cela le montrerait aussi, et pourquoi. Si vous passez du temps dans une bibliothèque système où vous ne savez pas (ou ne vous souciez pas) si elle est bloquée ou non, c'est la même chose.

Si cela prend plus de temps car un autre processus utilise une partie du temps processeur, cela n'a pas d'importance, car cela ne change pas beaucoup la façon dont votre code dépense son temps en pourcentage. Vous pourrez toujours savoir combien d'IO ou de sommeil ou de crunching vous faites, en pourcentage, et exactement pourquoi.

Si vous voulez quelque chose de plus joli, mais pas vraiment plus efficace, essayez Zoom.

+0

Ok, bonne astuce mais j'ai vraiment besoin d'avoir des timings. –

+0

@Jocelyn: Pouvez-vous obtenir un nombre N d'appels à la routine X? Le temps total multiplié par la fraction de temps X est actif, divisé par N, est le temps moyen par appel, à peu près. Maladroit, mais voilà. –