Zeit messen



  • Hallo Leute,

    also, ich bin noch C++ Neuling, und hab eigentlich ein ganz einfaches Problem, finde aber keine vernünftigen Infos dazu. Ich würde gerne die Zeit messen, die ein bestimmter Algorithmus von mir braucht, um etwas zu berechnen.

    Unter Java würde ich beim Startpunkt einfach ein (new Date()).getTime() machen und am Endpunkt auch, das gibt die Zeit in Millisekunden seit dem 1. Januar 1970, 00:00 zurück. Anhand der Differenz weiß man ziemlich genau, wie lange es gedauert hat. Wie kann ich denn sowas in C++ machen?

    Ich benutze Gentoo Linux, GCC 3.3.5 und glibc 2.3.4.

    Für schnelle Hilfe wäre ich dankbar 🙂

    Malte



  • Ich habe nochmal etwas weiter recherchiert und bin auf den Hinweis gestoßen, mir die Funktion gettimeofday anzuschauen.

    Das habe ich auch getan, aber ich krieg das irgendwie nicht so richtig gebacken. Zum einen erscheint mir das viel zu kompliziert, was ich gemacht habe, zum anderen funktioniert es auch nicht so richtig. Folgendes Testprogramm...

    #include <sys/time.h>
    #include <iostream>
    using namespace std;
    
    int main() {
    
      struct timeval tv;
      // time at begin and end
      long double begin, end;
    
      gettimeofday( &tv, NULL);
      begin = 10e6*tv.tv_sec + tv.tv_usec;
      sleep(2); // 2 Sekunden warten
      gettimeofday( &tv, NULL);
      end = 10e6*tv.tv_sec + tv.tv_usec;
      cout << "Time: " << (end-begin) << " microseconds (" << (end-begin)*10e-6 << " seconds)" << endl;
    }
    

    ...produziert bei mir folgenden Output:

    Time: 2.0001e+07 microseconds (200.01 seconds)

    200 Sekunden? Nein, das waren definitiv nur 2...

    Bitte helft mir! 😞



  • Mach aus deiner 10e6 eine 1e6 denn 10e6 ist eine 1 * 10⁷ ( 1* 10^7)



  • Btw, wenn Dir die Auflösung von man: time(1) reicht, dann versuchs doch mal damit; dann kannst Du Dein Programm von diesen ganzen Zeitmessungssachen freihalten.



  • schau mal im pronix-c-kurs unter time.h
    dort steht ausserdem das Thema ticks pro second,
    was dir bei deinen kurzen Zeiten mehr nützt.



  • Danke! Mit 1e6 geht's wunderbar... was für ein blöder Fehler aber auch 🙄

    time(1) hab ich mir mal angeguckt. Das ist für meine Zwecke nicht wirklich ausreichend, da ich gerne die Zeit von verschiedenen Prozessen in ein und demselben Programm messen möchte. Aber den Befehl kannte ich noch nicht, der könnte bestimmt mal nützlich werden 😉

    Die clock Funktion aus der time.h habe ich auch ausprobiert. Aber (wieder einmal...) krieg ich's nicht hin. Bzw. ich bekomme es nur auf die Hundertstel Sekunde genau hin, hätte aber gerne Mikrosekunden. Meine Motivation, die time.h statt der sys/time.h zu benutzen ist schlicht, dass erstere auf allen Systemen vorhanden ist. Es ist mir zwar egal, ob mein Programm sich auch unter Windows kompilieren lässt, aber es kann ja trotzdem nicht schlecht sein, sich von vorneherein einen möglichst "plattformunabhängigen" Stil anzugewöhnen.

    Hier mal eine modifizierte Version meines Testprogramms mit der clock Funktion (angelehnt an das Beispiel aus dem Pronix-C-Kurs):

    #include <time.h>
    #include <iostream>
    using namespace std;
    
    int main() {
    
      double time;
      // time at begin and end
      clock_t begin, end;
    
      begin = clock();
    
      for( long i = 0; i < 12345678; i++); // nicht mehr sleep(2), das zählt wohl nicht als CPU-Zeit...
    
      end = clock();
      time = (double)(end-begin) / (double)(CLOCKS_PER_SEC * 1e-6);
      cout << "Time: " << time << " microseconds (" << time*1e-6 << " seconds)" << endl;
    }
    

    Das führt bei mir zur folgenden Ausgabe:

    Time: 30000 microseconds (0.03 seconds)

    Egal, wie ich es verändere, es ist immer nur auf die Hunterstel Sekunde... geht das mit clock nicht genauer oder passieren mir da irgendwelche Rundungsfehler, oder sowas in der Art?

    Für erste bleibe ich also noch bei gettimeofday, aber es wäre cool wenn das mit clock klappen würde...

    Bitte helft mir nochmal! :p

    Und danke auch für den Tipp mit dem Pronix-C-Kurs 🙂 Dort habe ich auch den Hinweis auf die times Funktion aus der sys/times.h gefunden, aber die ist für meine Zwecke wiederrum übertrieben... und ich habe da Erklärungen zu gprof gefunden. Das ist natürlich echt nützlich, um zu sehen, welche Funktionen im Programm wirklich zeitfressend sind! Cool! 😃



  • clock() kann nicht höher auflösen. Es geht aber besser als gettimeofday() mit clock_gettime(). Beide sind jedoch nur POSIX



  • Jaah... sowas habe ich mir vorgestellt 🙂

    Aber... *seufz*... meint ihr, es würde einmal was auf Anhieb klappen? Jetzt will er gar nicht mehr kompilieren 😞

    #include <ctime>
    #include <iostream> 
    using namespace std; 
    
    int main() { 
    
      struct timespec tp; 
      // time at begin and end 
      double begin, end; 
    
      clock_gettime(CLOCK_REALTIME, &tp);
      begin = 1e9*tp.tv_sec + tp.tv_nsec; 
    
      for( long i = 0; i < 12345678; i++);
    
      clock_gettime(CLOCK_REALTIME, &tp);
      end = 1e9*tp.tv_sec + tp.tv_nsec; 
      cout << "Time: " << (end-begin) << " nanoseconds (" << (end-begin)*1e-9 << " seconds)" << endl; 
    
    }
    

    Ausgabe beim kompilieren:

    [21:45:21][~/dev/c++/damen]
    malte@fuchur $ g++ test.cpp
    /tmp/ccwqSts8.o(.text+0x1f): In function `main':
    : undefined reference to `clock_gettime'
    /tmp/ccwqSts8.o(.text+0x5e): In function `main':
    : undefined reference to `clock_gettime'
    collect2: ld returned 1 exit status
    

    Was ist jetzt falsch? Egal, ob ich nun <ctime> oder <time.h> include, derselbe Fehler kommt. Und das, obwohl in der /usr/include/time.h dick und fett steht:

    /* Get current value of clock CLOCK_ID and store it in TP.  */
    extern int clock_gettime (clockid_t __clock_id, struct timespec *__tp) __THROW;
    

    Zu Hülf! 😞
    (sorry, wenn ich mich blöd anstelle... fang halt gerade erstmal an)



  • Achja... und was meintest du mit "nur POSIX"? Soweit ich weiss, ist POSIX ein Standard, der Funktionen definiert, die über die Standard C++ Library hinausgehen, richtig?
    Meinst du, dass ich auch nicht unbedingt davon ausgehen kann, dass ich das auf allen Systemen habe? Und wenn ja, welche Funktion ist denn auf den "meisten" Systemen anzutreffen... gettimeofday oder clock_gettime?



  • einheitlix schrieb:

    Achja... und was meintest du mit "nur POSIX"? Soweit ich weiss, ist POSIX ein Standard, der Funktionen definiert, die über die Standard C++ Library hinausgehen, richtig?
    Meinst du, dass ich auch nicht unbedingt davon ausgehen kann, dass ich das auf allen Systemen habe? Und wenn ja, welche Funktion ist denn auf den "meisten" Systemen anzutreffen... gettimeofday oder clock_gettime?

    Posix ist das, woran sich eigentlich alle Unix Systeme halten. Windows hat das auch mal unterstützt. gettimeofday ist älter als clock_gettime und ich vermute, dass es von allen relevanten Plattformen unterstützt wird.



  • Alles klar... aber du hast auch keine Idee, woher der obige Fehler kommt? Das wurmt mich jetzt nämlich! 😉



  • einheitlix schrieb:

    Alles klar... aber du hast auch keine Idee, woher der obige Fehler kommt? Das wurmt mich jetzt nämlich! 😉

    clock_gettime ist in librt. Also -lrt benutzen.



  • Danke! Funktioniert jetzt alles wunderbar 🙂



  • vielleicht interressiert dich ja das hier auch noch:

    http://www.flipcode.com/cgi-bin/fcarticles.cgi?show=4&id=63830
    dort wird eine Methode beschrieben wie man exakt die Ticks mit hilfe eines speziellen CPU counters bestimmen kann.

    Hab ich selber mal hier im Forum gefunden. sehr empfehlenswert. Aber an x86 gebunden da ASM instructionen benutzt werden.



  • Hi Leute,

    kann ich die Funktion clock_gettime auch unter Windows XP benutzen?

    Ich bekomme nämlich mit dem Dev-Cpp Compiler folgende Fehler:

    17 [Warning] extra tokens at end of #include directive
    52 aggregate timespec tp' has incomplete type and cannot be defined 106CLOCK_REALTIME' undeclared (first use this function)
    106 `clock_gettime' undeclared (first use this function)

    Aber nach den vorhergehenden Beispielen müsste es ja funktionieren...

    Und wie mache ich das? (Nur für den Fall... (Bin Newbie))

    clock_gettime ist in librt. Also -lrt benutzen.

    Danke an alle,
    HdZ



  • Zeig bitte mal Deine #include<foobar.h>-Zeile; das sieht verheißungsvoll aus: "17 [Warning] extra tokens at end of #include directive". Passt gut zu den restlichen Fehlern.



  • hdz schrieb:

    Hi Leute,

    kann ich die Funktion clock_gettime auch unter Windows XP benutzen?

    Wenn Windows den POSIX Standard und da die Realtime Extensions unterstützt, dann ja. Aber ich glaube nicht, dass Windows das kann.



  • Zeig bitte mal Deine #include<foobar.h>-Zeile;

    Sorry, keine foobar.h
    Brauch ich die? In den Beispielen war davon nie die Rede. Er sagt auch dass es die Datei net gibt.

    Wenn Windows den POSIX Standard und da die Realtime Extensions unterstützt, dann ja. Aber ich glaube nicht, dass Windows das kann.

    Also bringt das hier eh nichts?

    Danke,
    HdZ



  • Oder meinst du meine #includes überhaupt?
    Die wären

    #include <iostream>
    #include <windows.h>
    #include <winsock2.h>
    #include <stdio.h>
    #include <stdlib.h>
    //#include <sys/time.h>
    #include <ctime>;
    


  • foobar.h war nur ein Platzhalter.
    Irgendwas passt laut Compiler mit dem #include in Zeile 17 nicht. Welches ist das denn?

    edit: Aber ob das unter Windows generell funktionieren kann oder nicht, weiß ich nicht. Soll ich Dich in ein geeignetes Forum verschieben?


Log in to reply