Chronométrer le temps d'exécution d'une fonction en C et à la µs

Chronométrer le temps d'exécution d'une fonction en C et à la µs - C - Programmation

Marsh Posté le 07-02-2013 à 12:49:54    

Bonjour,
 
Je viens vers vous car après 2 jours de recherche et d'essais, je n'arrive pas à trouver quoi que ce soit de concret sur les chrono en C.
Je commence à envisager de me pendre... [:al bundy]
 
Mon but : Chronométrer le temps d'exécution d'une fonction.  
 
En PHP, c'est 3 lignes de code et c'est précis à la microseconde. Ca prend 1min à coder.
En C, c'est le parcours du combattant :
Time.h n'est précis qu'a la seconde.
Glib est un rêve irréalisable, çà l'air génial sur le papier, mais c'est une galère insurmontable à installer. En regardant sur le net, un seul mec à réussi à le faire marcher, et il ne dit pas comment.
Sinon, tout le monde galère depuis des années et aucune solution n'est apportée dans aucun forum.
 
J'utilise RT linux (Real time), embarqué dans un microcontroller (mp5121e, freescale), avec une surcouche Xenomai.
 
Connaissez vous une méthode pour chronométrer à la miscroseconde le temps d'exécution d'une fonction ? ( pas de time.h, pas de saturation du processeur comme j'ai pu lire à certains endroits et pas de Glib).
 
Merci beaucoup.
 
 
Config:
---------
OS de dev : Ubuntu 10.04 LTS
OS target : Linux RT + surcouche Xenomai
IDE : Eclipse
 
 
 
 
 

Reply

Marsh Posté le 07-02-2013 à 12:49:54   

Reply

Marsh Posté le 07-02-2013 à 14:22:20    

En c, la fonction gettimeofday remplit une structure "timeval" qui contient un champ "tv_sec" et un champ "tv_usec".
 
Donc en 3 lignes de code et en 20 secondes, c'est codé !
 
On a vu plus complexe, comme parcours du combattant :)
 
Auto-edit : il faut voir comment cela fonctionne sur votre plate-forme cible, mais dans ce cas-là, la comparaison avec le PHP devient savoureuse !


Message édité par Farian le 07-02-2013 à 14:26:35
Reply

Marsh Posté le 07-02-2013 à 15:11:26    

Bonjour Farian,
 
Merci pour votre réponse.  
J'utilise actuellement la variable GetTimeOfDay.
Il est vrai que c'est codé en 3 lignes, mais le résultat n'est pas très précis (ordre de la miliseconde).
 
Je cherche pas tout les moyens à faire tomber cette précision à la microseconde (idéalement à la nano, mais là il faut se tourner vers une carte hardware dediée).
 
Pour le parcour du combattant plus complex, je trouve que l'installation de Glib est pas mal !  
Un sudo apt-get install libglib2.0-dev ne suffit pas. une fois qu'on lance le ./configure, une multitude de librairies sont manquantes (zlib1g-dev, libffi-dev, libpcre++-dev ...etc). Je les installes une par une, et une fois le tout installé, la galère continue à faire comprendre à Eclipse où la lib est stockée (/usr/include). Obligée de bidouiller avec des copier/coller en bougeant la lib de dossier pour qu'Eclipse la voit. Bref.
Une fois la lib reconnue sous Eclipse, impossible de compiler.  
Même en bidouillant, il y a toujours quelque chose qui ne va pas.
Mon cas rejoins le cas de beaucoup d'autre concernant Glib.  
C'est dommage car je crois que c'était la lib la plus précise en matière de chrono et de fonctions bas niveau...
 
J'ai fait la comparaison avec PHP, car c'est plus populaire (et d'un coté dérivé du C). La prochaine fois, je comparerai avec de l'ADA :)
 
Si quelqu'un à une autre solution, je suis preneur !  
Bonne journée à vous!

Reply

Marsh Posté le 07-02-2013 à 19:40:49    

Un truc dans ce gout la sur ton RT Linux?
 

Code :
  1. #include <time.h>
  2. #define NS_PER_SECOND 1000000000LL
  3. #define TIMESPEC_TO_NS( aTime ) ( ( NS_PER_SECOND * ( ( long long int ) aTime.tv_sec ) ) + aTime.tv_nsec )
  4.     struct timespec lLastTime;
  5.     struct timespec lCurrentTime;
  6.     clock_gettime( CLOCK_REALTIME, &lLastTime );
  7.     ....
  8.     clock_gettime( CLOCK_REALTIME, &lCurrentTime );
  9.     long long int lDifference = ( TIMESPEC_TO_NS( lCurrentTime ) - TIMESPEC_TO_NS( lLastTime ) );


 
A+,
 


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 08-02-2013 à 11:31:07    

Bonjour Gilou,
 
Merci pour votre réponse.  
En effet, cette fonction se rapproche grandement de ce que je veux faire.
J'ai fait quelque recherches et je suis tombé sur un excellent exemple.
 
Si ça peut servir à quelqu'un d'autre, c'est ici :  
http://www.jimscode.ca/index.php/c [...] me-example
 
Je vous tiens au courant quand à ma solution finale.  
 
Merci.  
Bonne journée.

Reply

Marsh Posté le 08-02-2013 à 12:23:09    

Bon, c'est la cata.  
Eclipse me sort : Undefined reference to 'clock_gettime'
 
J'ai pourtant :  
#include <time.h>
...
 clock_gettime(CLOCK_REALTIME, &(obj->starttime));
 
Je ne comprend pas pourquoi il ne voit pas cette librairie.
J'ai un autre programme.C qui utilise parfaitement cette librairie et cette fonction.
Mais sur mon projet actuel, il ne voit rien.
 
Est ce que ca ne viendrait pas du makefile ? Je le génère pourtant automatiquement avec Eclipse...
Variable d'environnement ? Pourquoi ça marcherai avec mon premier soft et pas le deuxième ? (ils sont dans le même workspace tout les deux).
 
Je perd un temps fou avec Eclipse et des problème de compilation (compilation de chose basique!!).
Je commence à être dégouté du C et surtout d'Eclipse ...  

Reply

Marsh Posté le 08-02-2013 à 13:01:37    

Eclipse me sort : Undefined reference to 'clock_gettime' ça doit être au niveau du link ce message.
Tu linkes ton programme avec la runtime library? (-lrt)
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 11-02-2013 à 09:10:43    

Bonjour Gilou,
 
Je link avec aucune librairie en particulier. Je laisse eclipse se débrouiller.
J'ai rajouter quelques path de librairies, mais c'est tout.
Comment fait on pour linker son programme avec la runtime library ?  
 
Merci.

Reply

Marsh Posté le 11-02-2013 à 11:37:37    

Bonjour,
Désolé, j'ai fait un lapsus dans mon post précédent, ce n'est pas de la run time library qu'il s'agit (laquelle est nommée libc), mais de la real time library (librt).
Je n'utilise pas éclipse pour faire du C (à la limite, pour faire du java, mais je n'aime pas cet outil) donc je ne peux te dire comment le configurer, et de toute façon, je ne laisse pas un outil "se débrouiller", je préfère être en contrôle des opérations d'un bout à l'autre. Dans la ligne de commande du Makefile, au moment du link, il faut avoir le flag -lrt (ie linker avec la librairie real time), comme dit précédemment (cette librairie implémente entre autres les timers haute résolution lorsque l'architecture hardware le permet).
A+,


Message édité par gilou le 11-02-2013 à 11:45:09

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 11-02-2013 à 12:16:31    

Gilou,
Merci pour votre réponse.
Je vais regarder pour ce flag -lrt.  
 Pour l'instant, je génère le makefile automatiquement par Eclipse.
Je n'aime pas ça non plus, mais c'est l'environnement de dev imposé et je n'y connais pas grand chose en makefile. (Je pense que je vais finir par m'y mettre).
En tout cas, je regarde la piste du flag -lrt !
Je vous tiens au courant.
Merci et bonne journée à vous.

Reply

Marsh Posté le 11-02-2013 à 12:16:31   

Reply

Marsh Posté le 11-02-2013 à 12:30:00    

Ou sinon, si vous repérez le path de la librt.a (ou .so ?), vous pouvez peut être aussi l'ajouter dans votre configuration d'éclipse.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 11-02-2013 à 17:25:33    

Alors, j'ai trouvé une solution me permettant de faire un compteur/chrono précis à la microseconde.
Après avoir perdu beaucoup de temps avec les librairies/Path, je me suis rabattu vers la fonction gettimeofday() (comme me l'a conseillé Farian).
Le but étant de remettre l'heure à 0, faisant office de remise à 0 du chrono.
Après il n'y a plus qu'a lire l'heure.
Bon j'avoue, c'est pas très beau ni ultra précis, mais ça me permet de chronométrer l'exécution d'une fonction.
Voici le code pour ceux que ça intéresse (n'hésitez pas à commenter/critiquer ce code) :
 

Code :
  1. #include <stdio.h>
  2. #include <signal.h>
  3. #include <unistd.h>
  4. #include <sys/mman.h>
  5. #include <sys/time.h>
  6. int i, useconde_start, useconde_stop, time_elapsed;
  7. char buffer[18];
  8. struct timeval tv;
  9. time_t curtime;
  10. //--------------------------
  11. // Reset time (=reset chrono)
  12. //----------------------------
  13. struct timeval tv;
  14. struct tm mytime;
  15. char * text_time;
  16. // Prepare the date
  17. mytime.tm_sec  = 00;    // Seconds
  18. mytime.tm_min  = 00;    // Minutes
  19. mytime.tm_hour = 00;   // Hours
  20. mytime.tm_mday = 11;   // Day of Month
  21. mytime.tm_mon  = 2;     // Month
  22. mytime.tm_year = 113; // Year (113 = 2013)
  23. tv.tv_sec = mktime(&mytime);
  24. tv.tv_usec = 0; // µsec reset
  25. settimeofday(&tv, NULL); // update de new date
  26. //--------------------------
  27. //  CHRONO (µseconde)
  28. //--------------------------
  29. gettimeofday(&tv, NULL);
  30. useconde_start = tv.tv_usec;  //Get the start time (in µs)
  31. // Do stuff
  32. gettimeofday(&tv, NULL);
  33. curtime=tv.tv_sec;
  34. useconde_stop = tv.tv_usec; //Get the stop time (in µs)
  35. time_elapsed = (useconde_stop - useconde_start);
  36. rt_printf("Time Elapsed : %ld µs \n",time_elapsed);


 
Merci pour votre aide et bonne journée à vous.

Reply

Marsh Posté le 12-02-2013 à 07:57:51    

[quotemsg=2

Code :
  1. //--------------------------
  2. //  CHRONO (µseconde)
  3. //--------------------------
  4. gettimeofday(&tv, NULL);
  5. useconde_start = tv.tv_usec;  //Get the start time (in µs)
  6. // Do stuff
  7. gettimeofday(&tv, NULL);
  8. curtime=tv.tv_sec;
  9. useconde_stop = tv.tv_usec; //Get the stop time (in µs)
  10. time_elapsed = (useconde_stop - useconde_start);
  11. rt_printf("Time Elapsed : %ld µs \n",time_elapsed);


 
Merci pour votre aide et bonne journée à vous.[/quotemsg]
 
Juste un petit détail : Tel quel, votre code vous renverra de temps en temps une valeur négative, car vous n'utilisez que le champ "microsecondes" de la structure (qui vaut entre 0 et 999999). La bonne façon de calculer le nombre de microsecondes entre t0 et t1 et 1000000*(t1.tv_sec - t0.tv_sec) + (t1.tv_usec - t0.tv_usec).
 
Bonne continuation à vous !


Message édité par Farian le 12-02-2013 à 07:58:48
Reply

Marsh Posté le 12-02-2013 à 09:27:42    

Bonjour Farian,
Bien vu ! Je modifie mon code.
Bonne continuation à vous!

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed