Methode/Funktion zum Zeitmessen einer Funktion gesucht.



  • Ich habe eine C bzw. C++ Programm geschrieben mit welchem ich eine bestimmte Anzahl von Speicherplätzen parallel belegen und wieder freigeben kann (malloc/free). Ich benutze dazu Threads und möchte nun herausfinden wie das Zeitverhalten des Programmes in abhängigkeit der Anzahl der Threads ist. Mit anderen Worten, ich will herausfinden mit wievielen parallel arbeitenden Threads ich Speicher dynamisch verwalten kann und wie schnell das geht.

    hier der Main-Teil:

    *main(int argc, char *argv[])
    {
    unsigned int t1,t2;
    double Wert;
    unsigned int Anzahl_Threads=atoi(argv[1]);

    t1=clock(); // Stoppuhr an

    threadstart(Anzahl_Threads);

    t2=clock(); // Stoppuhr aus

    Wert=(double)(t2-t1)/CLOCKS_PER_SEC;

    printf("%f ",(double) Wert);

    return 0;
    }
    *

    Wie man sieht, habe ich bereits hier eine Lösung unter Verwendung der Zeitfunktion <time.h> (fettgedruckt). Allerdings bekomme ich für eine große Anzahl von Threads (>150) sehr stakr fallende Werte heraus(0,01 sec) und diese stimmen keinesfalls, da die Zeit, in der ich auf eine Programmantowrt warte mit steigender Anzahl von Threads immer länger wird (ca 20 sec).

    Über eine zuverlässigere Funktion als Stoppuhr für mein Programm wäre ich sehr dankbar. Ich bitte darum Antworten leicht verständlich zu halten, da ich relativ neu unter den Programmierern bin.



  • clock_t  time;
    time = std::clock();
    
    // some intensive operation
    
    time = std::clock() - time;
    std::cout << "First attempt, time needed: "
    		<< time
    		<< std::endl;
    
    // the second intensive operation
    
    time = std::clock() - time;
    std::cout << "Second attempt, time needed: "
    		<< time
    		<< std::endl;
    


  • Wenn du unter Windows Arbeitest kannst du auch über die Winapi den Counter der CPU abfragen mit QueryPerformanceFrequency und QueryPerformanceCounter.

    Das sähe dann so aus:

    #include <windows.h>
    
    long long frequency;
    long long startTime;
    long long endTime;
    double timeInSeconds;
    
    //Frequenz abfragen, gibt Ticks pro Sekunde, muß nur einmal abgefragt werden Wert ist konstant
    QueryPerformanceFrequency(reinterpret_cast<LARGE_INTEGER*>(&frequency));
    
    //startzeit holen
    QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER*>(&startTime));
    
    //hier arbeiten erledigen
    
    //endzeit holen
    QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER*>(&endTime));
    
    timeInSeconds=static_cast<double>(endTime-startTime)/static_cast<double>(frequency);
    

    Der Counter is sehr genau. Weitere Infos kanst du dem MSDN und der Suchmaschine deines Vertrauens entnehmen.

    Die Frage wieso du als Programmieranfänger mit Threads arbeitest und davon 150 brauchst spare ich mir.



  • Danke, ich arbeite allerdings unter Linux (openSuse).

    @jesus: Danke, werd ich heut mal ausprobieren.



  • Ich habe es jetzt mit der Variante von "Jesus was black" ausprobiert, das Problem ist aber immer noch dasselbe. Die Zeitwerte stiegen erst simultan zur real-verstrichenen Zeit an und fallen dann allerdings wieder ab einem bestimmten Punkt, wobei die in der Realität verstrichene Zeit immer länger wird.

    Mit folgender Funktion bekomme ich richtige Werte, die allerdings sehr ungenau sind(+/- 1 sec):

    *time_t start,end;

    time (&start);
    threadstart(Anzahl_Threads);
    time (&end);

    dif = difftime (end,start);

    printf("%f ",(double) dif);*

    Problem hierbei ist, dass ich gerne Werte haben würde die auf die Millisekunde genau sind. Eine Lösung über clock() und CLOCKS_PER_SEC funktioniert jedenfalls nicht. Ich habe in anderen Foren auch schon gelesen, dass dies wahscheinlich daran liegt dass ich auf einem Mehrprozessorsystem arbeite.

    Für weiter Hilfe wäre ich sehr dankbar.



  • Du musst auf das Ende der Threads warten. Irgendwas in der Art threadwait(bla)



  • Ich bin auf der Suche nach genauen Zeitstempeln. Wobei es nicht die Uhrzeit sein muss, sondern eben einfach ein Wert der die Zeit repräsentiert, sodass verschiedene Zeiten in Relation gesetzt werden können:
    Konkret: Es werden ständig Messwerte erstellt und man soll sehen können, welcher Messwert neuer ist. Ich will also einfach jedem Messwert eine Erstellungszeit geben mit der ich ihn nachher mit anderen vergleichen kann.

    double Erstellungszeit = clock();
    std::cout << Erstellungszeit << std::endl;
    

    Leider kommt immer null raus 😞
    Soweit ich das verstanden habe zählt clock doch die CPU Ticks die seit Programmstart vergangen sind. Da sollte also doch ein Wert rauskommen! Außerdem können doch keine zwei Objekte zur gleichen Zeit erstellt werden, es liegen immer ein paar Ticks dazwischen. Kann ich also diese Erstellungszeit als eindeutige ID benutzen?


  • Mod

    Wenn's nur für Linux sein soll, dann kannst du so an genauere Zeiten kommen:

    #include <sys/time.h>  
    
        timeval start, end;
    
        gettimeofday(&start, NULL);
    
       /* Mach irgendwas tolles */
    
        gettimeofday(&end, NULL);
    
        long seconds  = end.tv_sec  - start.tv_sec;
        long useconds = end.tv_usec - start.tv_usec;
    
        long utime = ((seconds) * 1000000 + useconds); // vergangene Zeit in Mikrosekunden
    

    edit: Man beachte, dass die Auflösung des Zeitgebers nicht standardmäßig eine Mikrosekunde sein muss. Wie genau er tatsächlich ist, hängt von deinem System ab.

    edit2: Im Linux-Unterforum hier gibt es bestimmt Leute, die noch genauere Methoden kennen, falls es diese gibt. Das was ich hier zeige hat mir persönlich immer gereicht und ich war froh, dafür nicht zu tief in die Systemprogrammierung einsteigen zu müssen.



  • Da nicht dabei steht für welches system dus suchst verweis eich mal auf meinen post weiter oben, der QueryPerformanceCounter liefert mit jedem Aufruf vergangene Ticks seit dem Start des PCs.



  • Ich programmiere unter Linux! Und zwar nutzen wir ein Kontron Board das anscheinend sogar einen WatchDog hat. Kann man den zufällig zur genauen Zeitmessung brauchen?

    http://de.kontron.com/unternehmen/news-events/jrexce+der+erste+intel+celeron+35sbc+mit+usb+20.72.html


  • Mod

    fabske schrieb:

    Kann man den zufällig zur genauen Zeitmessung brauchen?

    Keine Ahnung, ich will jetzt nicht das gesamte datenblatt durchlesen, aber Zeitmessung unter Linux allgemein habe ich ja schon weiter oben erklärt.



  • SeppJ schrieb:

    aber Zeitmessung unter Linux allgemein habe ich ja schon weiter oben erklärt.

    Hab ich grad ausprobiert, funktioniert wunderbar! Vieles Danke 🙂



  • Da ich die boost lib einsetze habe ich mir nun eine Funktion geschrieben die die Zeit in Millisekunden seit dem 1.1.1970 ausgeben soll, also einen UNIX timestamp. Leider verrechnet der sich um ca. 2,5 Jahre 😞

    unsigned long HIRN::gibuZeitstempel2(void)
    {
      boost::posix_time::ptime Urzeitpunkt = boost::posix_time::from_iso_string("19700101T000000"); 
      boost::posix_time::ptime AktuelleZeit = boost::posix_time::microsec_clock::local_time();
      boost::posix_time::time_duration VergangeneZeit = AktuelleZeit - Urzeitpunkt;
      return (unsigned long) VergangeneZeit.total_milliseconds();
    
    };
    

    Weiß zufällig jemand warum?

    Außerdem würde ich gerne microseconds machen, aber leider passt das anscheinend nicht in eine long 😞



  • leider passt das anscheinend nicht in eine long

    Mit uint64_t oder int64_t aus stdint.h (oder aber cstdint) hast du garantierte 64 Bit breite Integer.



  • Vielen Dank!


Anmelden zum Antworten