Zeitmessung mit Boost::posix_time......



  • Hallo Leute!

    Mal wieder suche ich eine plattformunabhängige Lösung diesmal für eine Zeitmessung.

    Boost Bibliotheken stellen "hierfür" posix_time zu Verfügung.

    Die Zeit soll nur auf ms genau sein.

    Mein bisheriger Ansatz:

    boost::posix_time::time_duration td = boost::posix_time::milliseconds(10);
    
    	while(true)
    	{
    
    		boost::posix_time::ptime t1(boost::posix_time::microsec_clock::local_time());
    
                     //......hier wird was gemacht.......
    
                    boost::posix_time::ptime t2(boost::posix_time::microsec_clock::local_time());
    		boost::posix_time::time_duration dif = t2 - t1;
    
             {
    			std::cout << "Warnung: Leistungseinbruch im Thread'!!  Impulsrate von 10 ms Überschritten: " << dif << " ms\n";
    	}
    

    Im grunde steht alles auf folgender HP:
    http://www.boost.org/doc/libs/1_39_0/doc/html/date_time/posix_time.html

    Aber ich werde einfach nicht schlau draus!! Die Conversionen von ptime to std::string finde ich in den Bibliotheken nicht ( Beispiele sagen in "boost::gregorian::" wären die zu finden), der Vergleich "dif > td" funktioniert nicht, und naja es geht halt nichts 🙂

    evtl. weiß ja jemand bescheid oder hat das schonmal gemacht. Im Prinzip brauch ich nur die Dauer des Vorgangs in ms.

    Gruß
    WAR][FIRE 😋


  • Administrator

    Wo ist da eigentlich die konkrete Frage? Was ist dein Problem?

    Grüssli



  • Dravere schrieb:

    Wo ist da eigentlich die konkrete Frage? Was ist dein Problem?

    Grüssli

    Problem: Ich benötige eine Zeitmessung. Es gibt einen Startpunkt, danach wird irgendwas gemacht, und dann gibt es einen Endpunkt.
    Differenz = Endpunkt - Startpunkt <--- Diese Angabe brauche ich in ms!

    Bekomme ich mit Standartbibliotheken auch eine Zeitmessung hin?

    Ansatz:

    time_t start,end;
     double dif;
    
    time (&start);
    
    //irgendwas
    
    time (&end);
    
    dif = difftime (end,start);  //<---- liefert mir nur Sekunden, keine ms
    

    Das ist zu ungenau. Daher die Idee mit der Boost Klasse.

    Andere Vorschläge würden natürlich auch gehen, sofern sie plattformunabhängig sind.

    Gruß
    WAR][FIRE


  • Administrator

    http://www.cplusplus.com/reference/clibrary/ctime/clock/
    Allerdings hat es meistens keine Auflösung von einer Millisekunden.

    Auf Windows hat höchstens der QueryPerfomanceCounter eine so gute Auflösung.

    Und was ist eigentlich das Problem bei Boost? Willst du die Millisekunden haben? Dann suchst du total_milliseconds() ?
    http://www.boost.org/doc/libs/1_39_0/doc/html/date_time/posix_time.html#time_duration_accessors

    Grüssli



  • Dravere schrieb:

    http://www.cplusplus.com/reference/clibrary/ctime/clock/
    Allerdings hat es meistens keine Auflösung von einer Millisekunden.

    Auf Windows hat höchstens der QueryPerfomanceCounter eine so gute Auflösung.

    Und was ist eigentlich das Problem bei Boost? Willst du die Millisekunden haben? Dann suchst du total_milliseconds() ?
    http://www.boost.org/doc/libs/1_39_0/doc/html/date_time/posix_time.html#time_duration_accessors

    Grüssli

    Hmm ja ich bräuchte schon die Auflösung in ms.

    Bei Boost habe ich es schon mit "boost::posix_time::microsec_clock::local_time()" probiert. Funktioniert leider nicht bei millisec ist es genauso 😞

    Ich bau das ganze in einem Kommunikationsthread ein, der alle 10 ms eine Nachricht verschicken soll(TCP/IP). Wird dies nicht eingehalten soll der Benutzer eine Warnung erhalten.

    Gruß
    WAR][FIRE



  • und den durchschnitt der letzten 2 sekunden zu berechnen wäre wohl keine alternative?

    bb



  • unskilled schrieb:

    und den durchschnitt der letzten 2 sekunden zu berechnen wäre wohl keine alternative?

    bb

    eher unschön.

    Zudem könnte man dann etwas zu spät reagieren. Ich steuere einen Industrieroboter an. Wenn der anfängt alles auseinander zu rupfen sollte man schnell reagieren können 😃

    Gruß
    WAR][FIRE


  • Administrator

    10ms? Ich habe so meine Zweifel, dass dies mit Boost so einfach funktionieren wird. So wie ich Boost.DateTime verstanden habe, benutzt es für die microsec_clock std::clock und für die second_clock std::time .

    Auf Windows zum Beispiel, hat std::clock meistens eine Auflösung von 16ms. Also Intervalle unterhalb von 16ms gehen verloren.

    Wie die Genauigkeit auf Linux oder Mac ist, weiss ich nicht, kann mir aber schlecht vorstellen, dass die viel genauere Timer haben werden. Dafür muss man wohl spezialisierte Funktionen nehmen, wie eben auf Windows den QueryPerformanceCounter .

    Vielleicht mal noch auf www.sf.net nachschauen, ob es ein entsprechendes Framework zur genauen Zeitmessung schon gibt.
    Ansonsten muss du die Intervalle erhöhen, wenn das geht. Ein Intervall von 100ms sollten wohl alle schaffen können. Ist allerdings 10x mehr und immer noch nicht garantiert. Wenn du es so machst, dann solltest du dir auch mal Boost.Timer anschauen:
    http://www.boost.org/doc/libs/1_39_0/libs/timer/index.html

    Ist wohl deutlich besser für die Aufgabe geeignet.

    Grüssli



  • Da Frage ich mich wie man die Sleep/Wait Funktionen realisiert 😕 Die gibt es ja teilweise schon für Nanosekunden!

    Ich wusste nicht das die standard Timer so schlecht sind. Aber ich werd mir die Variante mit Boost.Timer mal angucken.

    Danke für die Hilfe!


  • Administrator

    WAR][FIRE schrieb:

    Da Frage ich mich wie man die Sleep/Wait Funktionen realisiert 😕 Die gibt es ja teilweise schon für Nanosekunden!

    Das sind ja platformspezifische Funktionen, welche auch ganz anders funktionieren als ein Timer. Kann schon sein, dass die eine bessere Auflösung haben. Allerdings gerade ein Sleep garantiert ja überhaupt nichts über die Länge, in der sich der Thread schlafen legt.

    WAR][FIRE schrieb:

    Ich wusste nicht das die standard Timer so schlecht sind. Aber ich werd mir die Variante mit Boost.Timer mal angucken.

    Benutzt std::clock 😉
    Deshalb sagte ich, nur falls du den Intervall erhöhst.

    Grüssli



  • Jep ich werds mal auf 100 - 200 ms entschärfen und im Prozessrechner des Roboters irgendwie was einbauen.

    Gruß
    WAR][FIRE



  • Hallo ein letztesmal für "heute"!

    Mir ist noch eingefallen das man das Problem evtl. mit dem einer Boost Wait Funktion lösen kann.

    Hier kann man die Wait Zeit ja auch in µs angeben.

    Man könnte in einem Thread einen Integer Wert inkrementieren und am Ende das Ergebnis ablesen.

    Also [Pseudocode]:

    funktion()
    {
         Starte Zeit Messungs Thread;
    
         ....... irgendwas
    
         Stoppe Zeit Messungs Thread;
    
         if( Dauer > 10 ms)
             cout << "WARNUNG...";
    }
    
    Zeit Messungs Thread()
    {
         int Dauer = 0;
    
         while(bis Stoppsignal)
         {
             boost::wait(1 ms);
             Dauer++;
         }
    }
    

    KAnn man das so machen oder ist es eher unüblich/schlecht/sonstiges?

    Gn8
    WAR][FIRE 🙂



  • Vielleicht ist die Posix-Funtion gettimeofday eine Alternative. Jedenfalls nutze ich diese immer fuer Zeitmessung. Hat Werte im Microsekundenbereich. Jedoch wirst du die Aufloesung nicht hoeher als die des Timerinterupts des Kernels sein. Als alternative bieten sich noch high resolution timer an, die aber nicht mehr plattformunabhaengig sind. Ist auch nicht weiter schlimm, da man diesen Code gut kapseln kann und fuer verschiedene Plattformen auch verschiedene Implementationen anbieten kann. Auch wird dein wait(1ms) nicht funktionieren, da Interupts oder Eventhandler ein Sleep unterbrechnen koennen. Etwas Bastelei fuer das korrekte Sleep sollte abhilfe schaffen. Die 5 Zeilen Code findest du bei google.



  • Ist zwar schon ein wenig her, aber hilft dir

    .total_milliseconds()
    

    des duration Objektes nicht?

    Ansonsten kannst du auch

    boost::this_thread::sleep(boost::posix_time::milliseconds(delay));
    

    benutzen, wobei du natürlich delay noch definieren müsstest.



  • stellt sich die Frage was genauer ist. Die Variante mit dem Sleep (bzw. wait)

    oder meine aktuelle realisierung:

    // Klasse Zeit Messung
    
    #include <ctime>
    #include "ZeitMess.h"
    #include <iostream>
    
    Zeitmessung::Zeitmessung(string zname){
        zn=zname;
        ticks_total=ticks=clock(); //Timer starten
        cycle=0;
    }
    
    Zeitmessung::~Zeitmessung()
    {
    
    }
    
    double Zeitmessung::runtime() const{
        return (double(clock())-double(ticks_total))/double(CLOCKS_PER_SEC) ;
    }
    

    Da würde ich nochmal gerne ein paar Meinungen hören von denen die es genauer wissen. Ich weiß es nämlich nicht. 😃

    Gruß
    WAR][FIRE


Anmelden zum Antworten