1. Dashboard
  2. Forum
    1. Unerledigte Themen
  3. Mitglieder
    1. Letzte Aktivitäten
    2. Benutzer online
    3. Team-Mitglieder
    4. Trophäen
    5. Mitgliedersuche
  4. Tutorial Bereich
  • Anmelden
  • Registrieren
  • Suche
Dieses Thema
  • Alles
  • Dieses Thema
  • Dieses Forum
  • Seiten
  • Forum
  • Lexikon
  • Erweiterte Suche
  1. Informatik Forum
  2. Webmaster & Internet
  3. Entwicklung

Zeitintervalle messen

  • Christoph R.
  • 5. September 2006 um 19:50
  • Unerledigt
  • Christoph R.
    16
    Christoph R.
    Mitglied
    Reaktionen
    36
    Punkte
    2.626
    Beiträge
    428
    • 5. September 2006 um 19:50
    • #1

    Hallo!

    Ich verwende die Funktion clock() in ctime um damit die Geschwindigkeit der Animationen meiner Grafikapplikation zu steuern. Die Applikation soll unter Windows, Linux und MacOS X laufen. Unter Windows läuft sie problemlos. Unter Linux und MacOS X gibt es Probleme mit der Ablaufgeschwindigkeit, die ich in folgendem Beispielprogramm simuliert habe:

    C
    #include <iostream>
    #include <ctime>
    
    
    int main(){
    
    
        clock_t t1, t2;
    
    
        t1 = clock();    // Referenzwert zum Programmstart speichern
    
    
        while (true){
            t2 = clock();    // Aktuellen Clock abfragen ...
            std::cout << double(t2 - t1) / CLOCKS_PER_SEC << std::endl; // ... und aus der Clock-Differenz auf die Laufzeit schließen
        }
    
    
        return 0;
    }
    Alles anzeigen


    Es sollten nun ständig Zahlen ausgegeben werden, die im Sekundentakt um genau 1 hochzählen. Unter Windows ist das auch so, unter Linux und MacOS zählen sie aber deutlich langsamer hoch (etwa alle 3 Sekunden um 1).

    Wenn ich das Programm so ändere dass die Ausgabe mit std::cout nur z.B. alle 100.000 Schleifeniterationen stattfindet, dann ist der Fehler deutlich geringer. Es sieht für mich jetzt so aus als ob clock() nur die Clocks im aktuellen Prozess misst und nicht systemweit (diese Vermutung habe ich nicht zuletzt deswegen, weil die Zeit, die während eines sleep()-Aurufs vergeht, offensichtlich nicht mitgezählt wird). Da std::cout sicher eine Kernelfunktion aufruft wird diese Zeit wohl auch nicht mitgezählt. Dabei sollte ja clock() soweit ich weiß pro Sekunde um genau CLOCKS_PER_SEC hochzählen, und zwar unabhängig von der Systemauslastung, dem aktuellen Prozess und sonstigen Gegebenheiten - zumindest gibt das ein Beispiel im Buch "Die C++-Programmiersprache" so zu verstehen. Dort wird angepriesen dass man mit dieser Funktion Zeitintervalle messen kann. Wenn aber Aufrufe von Kernelfunktionen nicht mitgezählt werden ist die Funktion ja für diesen Zweck nicht brauchbar.

    Wie kann ich Zeitintervalle zuverlässig und plattformunabhängig messen? Und vor allem soll wirklich die Zeit gemessen werden, und nicht wie lange der Prozess bearbeitet wurde. Schön wäre es auch noch, wenn es ein wenig exakter ginge als mit clock(), denn selbst wenn ich oben genanntes Problem nicht hätte wäre mir die Genauigkeit von 1/100 Sekunde unter MacOS zu ungenau (CLOCKS_PER_SEC ist dort 100, unter Windows ist es 1000; unter Linux sogar 1.000.000 - funktioniert aber wie gesagt nicht).

    mfg

  • Wolfibolfi
    37
    Wolfibolfi
    Mitglied
    Reaktionen
    186
    Punkte
    14.936
    Beiträge
    2.942
    • 5. September 2006 um 21:16
    • #2

    Unter Windows sollte man sowas mit SetTimer machen, deine Lösung ist ja "Busy Waiting". Eventuell SDL dafür verwenden, ist Plattformunabhängig, und bietet einen Timer.
    Oder einfach mal nachsehn, wie das bei SDL gemacht wird. Ist ja OSS.

    In einen FBO rendern ist wie eine Schachtel Pralinen - man weiß nie, was man kriegt.

  • Swoncen
    22
    Swoncen
    Mitglied
    Reaktionen
    1
    Punkte
    5.331
    Beiträge
    993
    • 5. September 2006 um 21:55
    • #3

    clock() misst nur die clocks im aktuellen Prozess. Ich verwende die Funktion eigentlich relativ häufig und bin damit auch zufrieden. Soviel ich weiß misst die Funktion mit einer genauigkeit von 1/1000 und nicht 1/100. Wenn du's aber genauer brauchst, verwend einfach QueryPerformanceCounter() - der is viel genauer.

    Wenn du nicht nur am aktuellen Prozess messen willst, kannst du timeGetTime() verwenden. Für welche Plattformen die Funktion ist, weiß ich nicht, aber kannst ja mal ausprobiern. Die liefert ein DWORD zurück, musst in der MSDN danach suchen, habs grad nicht bei der Hand. Musst halt dafür mmsystem.h und die winmm.lib in dein Projekt einfügen. Sag obs dir geholfen hat.


    mfg

    640K ought to be enough for anybody. :eek2:

  • Plantschkuh!
    24
    Plantschkuh!
    Mitglied
    Reaktionen
    163
    Punkte
    6.173
    Beiträge
    1.181
    • 5. September 2006 um 21:58
    • #4
    Zitat

    Es sieht für mich jetzt so aus als ob clock() nur die Clocks im aktuellen Prozess misst und nicht systemweit


    Zuallererst mißt clock() Prozessorzeit, nicht wall time. Und eben vielleicht nur Prozessorzeit als "user", also ohne Syscalls.

    Zitat

    Wie kann ich Zeitintervalle zuverlässig und plattformunabhängig messen?


    In ISO C++ gar nicht, du wirst eine Library brauchen. Nur aus Interesse, ist dein Grafikcode rein plattformunabhängig?

    Zitat

    (CLOCKS_PER_SEC ist dort 100, unter Windows ist es 1000; unter Linux sogar 1.000.000 - funktioniert aber wie gesagt nicht).


    Die Million ist auch nur Show, soweit ich das im Kopf hab zählt unter Linux die clock-Funktion eben in Tausenderschritten.

    *plantsch*

  • Christoph R.
    16
    Christoph R.
    Mitglied
    Reaktionen
    36
    Punkte
    2.626
    Beiträge
    428
    • 6. September 2006 um 08:32
    • #5

    Danke für die Antworten!

    Dann werde ich mir wohl eine andere Funktion suchen müssen.

    Zur Frage ob mein Grafikcode pattformunabhängig ist: ich habe eine Schicht eingeführt die ein paar plattformabhängige Initialisierungen vornimmt (z.B. Fenster erzeugen, OpenGL starten; GLUT und SDL wollte ich bewusst vermeiden). Darauf setzen dann weitere Schichten auf die vollkommen plattformunabhängig sind.

  • Wolfibolfi
    37
    Wolfibolfi
    Mitglied
    Reaktionen
    186
    Punkte
    14.936
    Beiträge
    2.942
    • 6. September 2006 um 10:09
    • #6

    Jo, wirst wohl für die Timer auch ne Schicht einführen müssen. Auch wenn du SDL nicht verwendest, kannst ja mal den Source durchwühlen, wie die das gemacht haben.

    In einen FBO rendern ist wie eine Schachtel Pralinen - man weiß nie, was man kriegt.

  • Christoph R.
    16
    Christoph R.
    Mitglied
    Reaktionen
    36
    Punkte
    2.626
    Beiträge
    428
    • 6. September 2006 um 10:45
    • #7
    Zitat von Wolfibolfi

    Auch wenn du SDL nicht verwendest, kannst ja mal den Source durchwühlen, wie die das gemacht haben.

    Habe ich gerade gemacht. Eigenartig ist dass dort auch clock() verwendet wird.

    Ich habe inzwischen die Funktion gettimeofday gefunden. Damit dürfte es funktionieren.

  • Swoncen
    22
    Swoncen
    Mitglied
    Reaktionen
    1
    Punkte
    5.331
    Beiträge
    993
    • 6. September 2006 um 10:51
    • #8

    Ich glaub gettimeofday gibts nur unter Windows, oder?

    640K ought to be enough for anybody. :eek2:

  • Christoph R.
    16
    Christoph R.
    Mitglied
    Reaktionen
    36
    Punkte
    2.626
    Beiträge
    428
    • 6. September 2006 um 10:58
    • #9
    Zitat von Swoncen

    Ich glaub gettimeofday gibts nur unter Windows, oder?

    Unter Linux und MacOS gibt es die Funktion sicher, da habe ich sie in time.h gefunden. Ich dachte eigentlich dass es sie unter Windows nicht gibt. Aber da gibt es dafür GetTickCount.

  • Maximilian Rupp 27. Dezember 2024 um 12:05

    Hat das Thema aus dem Forum Programmieren nach Entwicklung verschoben.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!

Benutzerkonto erstellen Anmelden

Benutzer online in diesem Thema

  • 2 Besucher

Rechtliches

Impressum

Datenschutzerklärung