OVH Cloud OVH Cloud

gprof

9 réponses
Avatar
ben64
Bonjour, je voudrai profiler un programme que j'ai fait.
J'utilise gprof, mais cela ne me donne pas des résultats convaiquants.
Je m'explique, prenons le programme suivant :

#include <stdlib.h>
#include <time.h>
#include <sys/time.h>

void fct1(const int s)
{
sleep(s);
}

void fct2(const int t)
{
int i;

for(i=0; i<t; i++);
}

int main(int argc, char * argv[])
{
fct1(10);
fct2(100000);
return EXIT_SUCCESS;
}

je le compile comme ca : gcc -static -pg -g gprof.c

Quand j'utilise gprof : gprof a.out gmon.out
Voilà la résultat :

Flat profile:

Each sample counts as 0.01 seconds.
no time accumulated

% cumulative self self total
time seconds seconds calls Ts/call Ts/call name
0.00 0.00 0.00 1 0.00 0.00 fct1
0.00 0.00 0.00 1 0.00 0.00 fct2
0.00 0.00 0.00 1 0.00 0.00 main

...

Ce n'est pas du tout ce à quoi je m'attendais. Comment chaque fct peut
prendre moins de 0.01 seconds, alors que je fais un sleep(10) ????

Deuxième problème, mon application est en réalité multi-threadé ! Il
paraît que sous linux (2.4.18), gprof ne peut profiler que le thread
principal, ce qui en général n'est pas très interessant. Une technique
existe et est décrite ici :
http://sam.zoy.org/writings/programming/gprof.html. Je voulais savoir si
cette technique était bien fiable et si les résultats obtenus étaient
réellement utilisables.

Merci d'avance

ben64

9 réponses

Avatar
[Sauron De Mordor]
essaye avec valgrind
tu t amusera bcp plus

ben64 wrote:

Bonjour, je voudrai profiler un programme que j'ai fait.
J'utilise gprof, mais cela ne me donne pas des résultats convaiquants .
Je m'explique, prenons le programme suivant :

#include <stdlib.h>
#include <time.h>
#include <sys/time.h>

void fct1(const int s)
{
sleep(s);
}

void fct2(const int t)
{
int i;

for(i=0; i<t; i++);
}

int main(int argc, char * argv[])
{
fct1(10);
fct2(100000);
return EXIT_SUCCESS;
}

je le compile comme ca : gcc -static -pg -g gprof.c

Quand j'utilise gprof : gprof a.out gmon.out
Voilà la résultat :

Flat profile:

Each sample counts as 0.01 seconds.
no time accumulated

% cumulative self self total
time seconds seconds calls Ts/call Ts/call name
0.00 0.00 0.00 1 0.00 0.00 fct1
0.00 0.00 0.00 1 0.00 0.00 fct2
0.00 0.00 0.00 1 0.00 0.00 main

...

Ce n'est pas du tout ce à quoi je m'attendais. Comment chaque fct peu t
prendre moins de 0.01 seconds, alors que je fais un sleep(10) ????

Deuxième problème, mon application est en réalité multi-threadé ! Il
paraît que sous linux (2.4.18), gprof ne peut profiler que le thread
principal, ce qui en général n'est pas très interessant. Une tech nique
existe et est décrite ici :
http://sam.zoy.org/writings/programming/gprof.html. Je voulais savoir s i
cette technique était bien fiable et si les résultats obtenus ét aient
réellement utilisables.

Merci d'avance

ben64



Avatar
Marc Boyer
ben64 wrote:
Ce n'est pas du tout ce à quoi je m'attendais. Comment chaque fct peut
prendre moins de 0.01 seconds, alors que je fais un sleep(10) ????


Parce que gprof mesure le temps de travail, et quand un code
dort, il ne travaille pas beaucoup.
Si tu veux faire un code qui calcule pendant 10 secondes, fait
plutôt quelque chose du genre
void foo(){
long l=0;
time_t start, current;
for(time(&start); time(&current), current-start<&0; ){
/* Un peu de code qui travaille, genre
l+= (l<1000)?(l+3):(l/2-1);
}
}
/* code non testé et crade par pur plaisir */

Deuxième problème, mon application est en réalité multi-threadé ! Il
paraît que sous linux (2.4.18), gprof ne peut profiler que le thread
principal, ce qui en général n'est pas très interessant.


Parfois, pour certains objectifs, il faut se tourner
vers des outils payants. Je me souviens que l'environnement
de développement de Sun faisait ça à merveille.

Marc Boyer
--
Lying for having sex or lying for making war? Trust US presidents :-(

Avatar
ben64
OK merci pour la reponse. Alors du coup j'ai une autre question. Je suis
bien content de savoir qu'une fonction me prend 40% de temps processeur.
Cependant si elle me prend 0.001% de temps global, je ne vais pas
m'attarder dessus. Car supposons que j'arrive à améliorer ses
performances, le temps de réponse pour l'utilisateur sera complètement
négligeable et il ne verra pas la différence. Alors comment trouver un
moyen fiable pour savoir quel bout de code prend vraiment du temps ?
Cela me permettra de focaliser mon travail sur ce bout de code et
d'ainsi améliorer les performances globales (temps de réponse pour
l'utilisateur).

Merci d'avance

ben64

Marc Boyer wrote:
ben64 wrote:

Ce n'est pas du tout ce à quoi je m'attendais. Comment chaque fct peut
prendre moins de 0.01 seconds, alors que je fais un sleep(10) ????



Parce que gprof mesure le temps de travail, et quand un code
dort, il ne travaille pas beaucoup.
Si tu veux faire un code qui calcule pendant 10 secondes, fait
plutôt quelque chose du genre
void foo(){
long l=0;
time_t start, current;
for(time(&start); time(&current), current-start<&0; ){
/* Un peu de code qui travaille, genre
l+= (l<1000)?(l+3):(l/2-1);
}
}
/* code non testé et crade par pur plaisir */


Deuxième problème, mon application est en réalité multi-threadé ! Il
paraît que sous linux (2.4.18), gprof ne peut profiler que le thread
principal, ce qui en général n'est pas très interessant.



Parfois, pour certains objectifs, il faut se tourner
vers des outils payants. Je me souviens que l'environnement
de développement de Sun faisait ça à merveille.

Marc Boyer



Avatar
Marc Boyer
ben64 wrote:
OK merci pour la reponse. Alors du coup j'ai une autre question. Je suis
bien content de savoir qu'une fonction me prend 40% de temps processeur.
Cependant si elle me prend 0.001% de temps global, je ne vais pas
m'attarder dessus. Car supposons que j'arrive à améliorer ses
performances, le temps de réponse pour l'utilisateur sera complètement
négligeable et il ne verra pas la différence. Alors comment trouver un
moyen fiable pour savoir quel bout de code prend vraiment du temps ?
Cela me permettra de focaliser mon travail sur ce bout de code et
d'ainsi améliorer les performances globales (temps de réponse pour
l'utilisateur).


Ben, hormis les cas de "sleep" explicite, c'est généralement
l'utilisation des ressources qui prends du temps. Non ?

Marc Boyer
PS: Quand on répond à un message, on réponde "après", en ayant pris soin
de ne conserver du message d'origine que ce qui est pertinent pour la suite
de la discussion.
--
Lying for having sex or lying for making war? Trust US presidents :-(

Avatar
Jean-Marc Bourguet
Marc Boyer writes:

Ben, hormis les cas de "sleep" explicite, c'est généralement
l'utilisation des ressources qui prends du temps. Non ?


Les attentes d'IO. Et on peut arriver a gagner pas mal en les
reorganisants. J'ai vu un ordre de grandeur par rapport a du code qui
se pretentait optimise.

A+

--
Jean-Marc
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
ben64
Ben, hormis les cas de "sleep" explicite, c'est généralement
l'utilisation des ressources qui prends du temps. Non ?


Par exemple, j'ai une fonction qui nécessite pas mal de calcul, gprof
me dit qu'elle représente 40% du temps écoulé (40 us de temps en réalité).
Une autre fonction fait un ensemble de requêtes sur une base de
données. En temps processeur, il n'y a pas grand chose à faire, le plus
long est d'attendre la réponse de la base de données. gprof me dit
qu'elle représente 0% du temps (2000 us en réalité).
Si je me fie à gprof, je vais travailler sur ma première fonction,
alors que le temps réel de celle-ci est complètement négligeable par
rapport à l'autre. Je ferai mieux de passer du temps à réfléchir sur mes
requêtes SQL. Ceci n'est qu'un exemple, mais prouve que les résultats de
gprof sont dans mon cas (ou dans mon utilisation de celui-ci)
complètement inutilisables.

PS: Quand on répond à un message, on réponde "après", en ayant pris soin
de ne conserver du message d'origine que ce qui est pertinent pour la suite
de la discussion.


Ok, désolé.

Merci

ben64

Avatar
ts
"b" == ben64 writes:






b> Par exemple, j'ai une fonction qui nécessite pas mal de
b> calcul, gprof me dit qu'elle représente 40% du temps écoulé (40 us de
b> temps en réalité).

Toutes les librairies, que vous utilisez, ne sont pas compilées avec
l'option -pg, c'est pour cela que gprof vous donne des résultats qui vous
semblent étranges. Certains linux proposent (la debian), en option, ces
librairies compilées avec le bon switch (libc6-prof par exemple)


--

Guy Decoux





Avatar
Marc Boyer
Jean-Marc Bourguet wrote:
Marc Boyer writes:
Ben, hormis les cas de "sleep" explicite, c'est généralement
l'utilisation des ressources qui prends du temps. Non ?


Les attentes d'IO. Et on peut arriver a gagner pas mal en les
reorganisants. J'ai vu un ordre de grandeur par rapport a du code qui
se pretentait optimise.


Oui, tout à fait. Quand j'ai écris mon post, je me disais que
j'oubliais un truc...
Quand je pense qu'en plus je fais des TPs ou on montre comment
le fait de séparer les threads d'IO et de traitement augmente
les perfs.

Marc Boyer, mea culpa
--
Lying for having sex or lying for making war? Trust US presidents :-(


Avatar
ben64
Toutes les librairies, que vous utilisez, ne sont pas compilées avec
l'option -pg, c'est pour cela que gprof vous donne des résultats qui vous
semblent étranges. Certains linux proposent (la debian), en option, ces
librairies compilées avec le bon switch (libc6-prof par exemple)


Merci beaucoup, je ne le savais pas. J'espère que la debian m'offre la
possibilité d'avoir la libpq (postgresql) compilé avec l'option pg,
sinon je la recompilerai à la main. Merci à tous de votre aide.

ben64