• 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:


    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

  • 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.

  • 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:

  • 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*

  • 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.

  • 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.

Jetzt mitmachen!

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