Zeitmessung mit timer in Thread sinnvoll?



  • Hallo,
    ich habe eine Frage zur Zeitmessung unter Linux. Ich wuerde gerne ein Programm schreiben und darin eine eine Operation auf einer Datenstruktur mehr oder weniger genau zeitlich messen. Nun, habe ich mir ueberlegt dazu die Operation in einen Thread zu packen und parallel einen Timerthread zu erstellen, der gestoppt wird, wenn die Operation abgeschlossen ist. Den Timer will ich mit Hilfe <sys/time.h> erstellen (kenne ich leider auch noch nicht gut genug). Die Threads will ich als POSIX Threads implementieren. Wie gesagt ich will NICHT den kompletten Programmablauf zeitlich messen (wie etwa mit "time") sondern eben nur eine Operation auf einer Datenstruktur innerhalb des Programmes.

    Ist das Vorgehen so ueberhaupt sinnvoll (nur eine CPU)?
    Wie schaetze ich dabei den Fehler ab?
    Worauf muss ich beim erstellen des Timer Threads achten?
    Sollte ich die Scheduling Policy oder andere Einstellungen (pthread_attr_t variable) ggf fuer den Timer Thread veraendern oder reichen die "default" Settings dafuer aus?



  • Wieso sollte man da einen Thread nehmen? Ist nicht gerade sinnvoll.
    Einfach die Zeit vor und nach der Operation speichern und dann die Differenz nehmen. Ist genau und beeinflusst die Operation an sich nicht.

    EDIT:

    #include <stdio.h>
    #include <time.h>
    
    /*
     * gcc -lrt ...
     */
    
    int main()
    {
    	struct timespec ts_res, ts_start, ts_end;
    	clock_getres(CLOCK_MONOTONIC, &ts_res);
    
    	printf("Resolution: %lus and %lins\n", ts_res.tv_sec, ts_res.tv_nsec);
    
    	clock_gettime(CLOCK_MONOTONIC, &ts_start);
    
    	/* do something */
    
    	clock_gettime(CLOCK_MONOTONIC, &ts_end);
    
    	printf("Elapsed time: %luns\n", (ts_end.tv_sec - ts_start.tv_sec) * 1000000000 + ts_end.tv_nsec - ts_start.tv_nsec);
    
    	return 0;
    }
    

    Hat bei mir ne Auflösung von 1ns... also viel zu genau 😉



  • warum ein Thread?

    zeit1 = zeitmessen();
    operation();
    dzeit = zeitmessen() - zeit1;
    

    Um die Zeit zu messen könntest du zB man: gettimeofday benutzen.



  • rüdiger schrieb:

    Um die Zeit zu messen könntest du zB man: gettimeofday benutzen.

    Zum Messen von Zeiten sollte immer clock_gettime(CLOCK_MONOTONIC, struct timespec *tp); genommen werden. Da diese Zeit immer weiterläuft und nicht durch ntp oder sonst wie verfälscht werden kann.



  • Ah, ok, danke!!! - ich hatte heute nur mit

    itimerval
    

    Variablen herumexperimentiert. Vielen dank fuer den Tipp mit

    clock_gettime(CLOCK_MONOTONIC, struct timespec *tp);
    

    👍



  • lagalopex schrieb:

    rüdiger schrieb:

    Um die Zeit zu messen könntest du zB man: gettimeofday benutzen.

    Zum Messen von Zeiten sollte immer clock_gettime(CLOCK_MONOTONIC, struct timespec *tp); genommen werden. Da diese Zeit immer weiterläuft und nicht durch ntp oder sonst wie verfälscht werden kann.

    Ah ok. Hast ja recht 🙂



  • Nachtrag: ich schaffe es nicht den obigen Code zu kompilieren, der Linker kann "clock_getres()" und "clock_gettime()" nicht finden. Muss ich dem Compiler/Linker im Makefile noch was dazugeben?

    ...: undefined reference to `clock_getres'



  • Wenn wir schon ueber Timers reden:

    Ich habe einiges ueber timers gelesen. Nirgendswo wird der Unterschied zu
    angebotenen Timers deutlich dargestellt. Kann man die Timers so unterscheiden:

    CLOCK_REALTIME: ist die Prozessorzeit, die unabhaengig von dem Zustand meines Prozesses ist und immer weitertickt.
    Das heisst: Der finish timespec structure koennte vergangenen Zeiten beinhalten wo mein Prozess suspendiert war(wenn es ueberhaupt suspendiert wird..)..
    CLOCK_PROCESS_CPUTIME_ID: ist die Prozesszeit, was nur tickt wenn mein Prozess im Zustand "Laufend" ist.
    CLOCK_THREAD_CPUTIME_ID: Genause wie Prozesszeit, aber fuer den Thread-Einheit. (was sinnvol fuer Thread Zeitmessungen waere..

    /* ..*/ 
    struct timespec start, finish ;
    /*..*/
     clock_gettime(CLOCK_REALTIME, &start) ;
    /*.. time passed  - process -could- be suspended by dispatcher */
    clock_gettime(CLOCK_REALTIME, &finish) ; 
    /* calculate diff */
    

    lagalopex schrieb:

    Zum Messen von Zeiten sollte immer clock_gettime(CLOCK_MONOTONIC, struct timespec *tp); genommen werden. Da diese Zeit immer weiterläuft und nicht durch ntp oder sonst wie verfälscht werden kann.

    Dann muesste der CLOCK_MONOTONIC mit einer unsigned long wert anfangen zu
    zaehlen, wenn das Betriebsystem hochgefahren ist, oder? Messe ich auch die
    suspendierte Zeiten vom Prozess mit?

    Gruss,



  • Aus der Manualpage:

    NOTE
           Most systems require the program be linked with the librt library to use these functions.
    

    Also -lrt.



  • @Fabeltier: Zeile 5 🙄

    CLOCK_REALTIME : Ist die normale Systemuhr. Also Sekunden seit 1970 und kann halt verstellt werden.
    CLOCK_MONOTONIC : Tickt seit dem Booten (an sich egal seit wann) unaufhörlich und unveränderlich.
    CLOCK_PROCESS_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID : Tickt nur wenn der Prozess/Thread gerade läuft. Also zB würde ein sleep(1); hier praktisch ignoriert werden. Manchmal ganz praktisch, aber evtl spielen ja andere Prozesse/Threads auch eine Rolle.



  • lagalopex schrieb:

    CLOCK_REALTIME : Ist die normale Systemuhr. Also Sekunden seit 1970 und kann halt verstellt werden.
    CLOCK_MONOTONIC : Tickt seit dem Booten (an sich egal seit wann) unaufhörlich und unveränderlich.
    CLOCK_PROCESS_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID : Tickt nur wenn der Prozess/Thread gerade läuft. Also zB würde ein sleep(1); hier praktisch ignoriert werden. Manchmal ganz praktisch, aber evtl spielen ja andere Prozesse/Threads auch eine Rolle.

    Danke! 👍


Anmelden zum Antworten