Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

1

11.04.2014, 15:31

C++11 FPS mit std::chrono ermitteln

Hallo,
ich will gerade meine "Timer" Klasse schreiben, die den C++11 Namespace "std::chrono" etwas vereinfachen soll.
Momentan sieht meine Klasse so aus:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
class Timer
{

public:

void BeginStopWatch()
{
    startTime_ = std::chrono::system_clock::now();
}

long long EndStopWatch()
{
    auto endTime = std::chrono::system_clock::now();
    return std::chrono::duration_cast<std::chrono::microseconds>(endTime - startTime_).count();
}

double FrameRate()
{
    auto duration = EndStopWatch();
    BeginStopWatch();

    if (duration > 0)
        return 1000000.0 / static_cast<double>(duration);
    
    return 0.0;
}

private:

std::chrono::system_clock::time_point startTime_;

};

Leider passiert es, dass "FrameRate()" Zeitweise nur 50.0 oder 100.0 zurückliefert :-(
Manchmal aber auch 58.0 bis 62.0 (also in etwa die Herz Zahl meines Monitors).
Mich wundert, dass das unregelnmäßig funktioniert oder gar nicht funktioniert.

Ich meiner alten Engine hatte ich das noch mit den WinAPI Funktionen "QueryPerformanceCounter" etc. gemacht, aber das ist halt Platform abhängig.
Und da C++11 nun mit "std::chrono" portablen Code liefert, würde ich das gern damit machen.

Hat jemand eine Idee, wie man die Frame-Rate (bzw. FPS) mit std::chrono in C++11 so genau wie möglich ermitteln kann?

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

2

11.04.2014, 15:39

Ich würde dir empfehlen, die "Frames pro Sekunde" wörtlich zu nehmen:
Zähle einfach die fertiggestellten Frames innerhalb der letzten Sekunde. Dann kriegst du wesentlich stabiliere und sinnvollere Werte.

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

3

11.04.2014, 15:50

Dann kriegst du wesentlich stabiliere und sinnvollere Werte.

Da bin ich anderer Meinung.

Angenommen V-Sync ist deaktiviert und die Frame-Raten variieren recht stark alle paar Millisekunden.
Dann braucht man einen Mechanismus, der die Geschwindigkeiten von z.B. den Animationen reguliert.
Wenn man das anhand der FPS nur jede Sekunde aktualisieren kann, sieht es aus, als ob das Spiel ruckeln würde, obwohl es mit 100 bis 200 FPS laufen kann.

Ich will ja bewusst in jedem Frame eine Approximation (aber eine sehr genaue) für die derzeitige Frame Rate haben.
Also eben die 1. Ableitung der Zeit in diesem Punkt (bzw. Frame). Das ist also ein Grenzwertproblem wie auch bei den Ableitungen von Graphen.
Eine Ableitung über 60 Frames hinweg wäre keine sehr genaue Ableitung, aber genau das hätte ich, wenn ich die Frames zählen würde, so wie du es vorgeschlagen hast.

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

4

11.04.2014, 16:21

Soweit ich weiß, sind die C++11 Timer in MSVC alle nicht auf Basis des wesentlich präziserem "QueryPerformanceCounter"s implementiert.
Ich würde dir empfehlen, unter Windows weiterhin diese Funktion zu nutzen.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Spiele Programmierer« (11.04.2014, 19:09)


LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

5

11.04.2014, 16:25

Ok danke. Dann mache ich das so.

Hatte ich mir schon fast gedacht, ein Aufruf von 'Duration Cast' "mit "std::chrono::microseconds" hat nämlich immer nur 3 Nullen hinten dran gehabt.
Also letzt endlich gibt die Präzision nur bis auf Millisekunden.

Schade, so portabel scheint die STL dann doch nicht zu sein :-(

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

6

11.04.2014, 16:27

@Lukas:
Ach so, ich war davon ausgegangen, dass du die FPS nur für die Anzeige brauchst.
Rechnen würde man doch nicht mit der Framerate, sondern mit der vergangenen Zeit.
Kennst du schon den Wiki-Artikel Framerate-unabhängige Spiellogik?

7

11.04.2014, 16:27

RE: C++11 FPS mit std::chrono ermitteln

Leider passiert es, dass "FrameRate()" Zeitweise nur 50.0 oder 100.0 zurückliefert :-(
Manchmal aber auch 58.0 bis 62.0 (also in etwa die Herz Zahl meines Monitors).
Mich wundert, dass das unregelnmäßig funktioniert oder gar nicht funktioniert.

Ich meiner alten Engine hatte ich das noch mit den WinAPI Funktionen "QueryPerformanceCounter" etc. gemacht, aber das ist halt Platform abhängig.
Und da C++11 nun mit "std::chrono" portablen Code liefert, würde ich das gern damit machen.

Hat jemand eine Idee, wie man die Frame-Rate (bzw. FPS) mit std::chrono in C++11 so genau wie möglich ermitteln kann?


Ich weiß nicht ob es daran liegt aber was passiert zwischen 2 Frames wenn die Rechenzeit ein anderes Programm bekommt?

Ich bin da auch David's Meinung FPS über eine Sekunde zu ermitteln. Wenn es dir darum geht fest zustellen ob irgendwelche Funktionen langsam sind, würde ich die Zeit messen die dann die Funktion wirklich brauchst.

Gruß Koschi
Wer aufhört besser werden zu wollen hört auf gut zu sein!

aktuelles Projekt:Rickety Racquet

Beiträge: 1 223

Wohnort: Deutschland Bayern

Beruf: Schüler

  • Private Nachricht senden

8

11.04.2014, 16:52

Ruckeln kann halt auch entstehen, wenn die Frames nicht gleichmäßig gerendert werden.
Wenn das erste 10ms braucht, das zweite 80ms, dann 10ms, 10ms, 80ms, 10ms...
Die Zeit die ein Frame zum rendern braucht direkt zu ermitteln, kann da schon wesentlich hilfreicher sein.

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

9

11.04.2014, 17:40

@David: Danke für den Link, schaue ich mir bei Gelegenheit mal an ;-)
Jetzt habe ich erst mal wieder die "QueryPerformanceCounter" Methoden unter Windows verwendet.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

10

11.04.2014, 18:38

Ich frage mich immer noch, was du mit dem FPS-Wert rechnen willst ...
Und was meintest du eigentlich mit "1. Ableitung der Zeit"?
Vielleicht denkst du auch viel zu kompliziert. Du solltest den Artikel wirklich lesen!

Werbeanzeige