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

1

20.05.2018, 17:31

Verständnis-Problem mit std::chrono::time_point objekt

Hallo Zusammen :)

Ich habe folgendes Problem:
Ich versuche die Zeit meines Spiels pro Schlaufendruchgang mittels std::chrono::high_resolution_clock auszumessen, aber irgendwie gelingt es mir nicht dessen Struktur nachzuvollziehen.

Ich sollte wohl an dieser Stelle erwähnen, dass mir noch die Routine mit dem Umgang von Templates fehlt, resp. ist dieser Syntax für mich nicht einfach zu verstehen, wenn eine Bibliothek damit arbeitet.

Was ich bis jetzt zu verstehen glaube ist, dass mir die Funktion std::chrono::high_resolution_clock::now() ein Objekt vom Typ std::chrono::high_resolution_clock::time_point zurückgibt.
?(
eigentlich hatte ich vor ein zeitdelta zu bestimmen mit folgender Methode:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Deklaration von zeitmarke und zeitdelta
std::chrono::high_resolution_clock::time_point zeitmarke;
std::chrono::high_resolution_clock::time_point zeitdelta;
...
...
...
...
// zeitmarke das erste mal initialisieren
zeitmarke = high_resolution_clock::now();

while(running){

// zeitdelta für einen Schleifendruchgang berechnen
zeitdelta = std::chrono::high_resolution_clock::now() - zeitmarke;
// zeitmarke aktualisieren
zeitmarke += zeitdelta;

// Simulation
// Rendern
} 
}


Meine Überlegung war, std::chrono::high_resolution_clock::now() nur einmal pro Schleifendruchgang abzufragen, damit auch wirklich die ganze Zeit erfasst wird. Die zeitmarke aktualisiere ich dann, indem ich das zuvor berechnete zeitdelta wieder draufpacke.

Nur spielen mir da diese time_point objekte nicht mit, obwohl es eigentlich laut Referenz danach aussieht, dass der Substraktion-Operator für diese Klassenobjekte überladen ist.

In einem anderen Beispiel, dass ich gefunden habe wird die Dauer wie folgt berechnet:

Quellcode

1
std::chrono::duration<double> timedelta = end - start;


Ich verstehe an diesem Punkt nicht, wieso meine Methode nicht funktioniert. Weil offensichtlich lassen sich ja diese time_point Objekte per Substraktion verrechnen.
Was genau macht denn "std::chrono::duration<double>" ?( ist das eine Art cast? Oder ist duration eine Funktion? :-)

Vielen Dank für die Hilfe und schöne Pfingsten
Gruss neptun

2

20.05.2018, 18:08

Einem time_point kannst du keine Zeitdifferez zuweisen. Ergibt keinen Sinn, ist schließlich ein Zeitpunkt. Subtraktion von zwei high_resolution_clock::time_point ergibt high_resolution_clock::duration:

Quellcode

1
2
3
4
high_resolution_clock::time_point end, start;
high_resolution_clock::duration delta = end - start;
//oder einfach
auto delta = end - start;

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

3

20.05.2018, 18:37

std::chrono::duration<double> ist ein Datentyp. Genau wie ein int. Diese Duration ist zudem ein Template mit dem Spezialtyp double. Ich glaube es ist an der Stelle für dich sinnvoller dich mal mit Templates zu beschäftigen, denn die sind das A und O von C++.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

4

20.05.2018, 18:57

Ok vielen Dank, das bringt Licht in die Sache. :)

Seh ich das richtig, dass ich mit:

Quellcode

1
__int64 zeitmarke = chrono::high_resolution_clock::now().time_since_epoch().count();


direkt an die Nanosekunden, die seit dem Systemstart vergangen sind, herankomme?

also quasi analog zu SDL_GetTicks() nur diesmal mit nano - statt milli Sekunden?

Kriegt man das überhaupt hin - mit nur einem Befehl - dass die Methode count() des duration-objekts einen double für die Sekunden zurückgibt?

Gruss neptun

Edit:
@BlueCobold
Danke für den Hinweis.
Völlig fremd sind mehr zwar Templates nicht mehr - aber ich bin noch ein bisschen unbeholfen.
Ich arbeite aber dran ;)

Demnach ist std::chrono::duration<double> eine Klasse, die mir im diesem Fall mit der Methode count() ein double zurückliefert?

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »neptun« (20.05.2018, 19:32)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

5

20.05.2018, 22:58

time_since_epoch liefert ganz sicher nicht die Zeit seit dem Systemstart. Sonst stünde da ja nicht "epoch". Einen Double willst du für so einen langen Zeitraum für Nanosekunden auch gar nicht haben, wenn du mal darüber nachdenkst wie viele Stellen dieser Zahl durch einen Double schon gar nicht mehr dargestellt werden könnten. Ein int64 ist da schon ganz richtig gewählt.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

6

21.05.2018, 11:07

Danke für deine Hilfe BlueCobold :-)

time_since_epoch liefert ganz sicher nicht die Zeit seit dem Systemstart. Sonst stünde da ja nicht "epoch".

Ich hatte es jetzt einfach so verstanden, dass mit "chrono::high_resolution_clock::now().time_since_epoch().count();" mir einfach die Zeit seit Systemstart in Nanosekunden als __int64 zurückgegeben wird.
Da mir die Methode "time_since_epoch()" des time_point Objektes als Rückgabewert ein Objekt des Typs duration liefert, in welchem die Methode count() dann den entsprechenden Wert zurückgibt.
Den Wert, den ich damit zurückbekomme trifft immer genau die Zeit, seit Windwos-Start.
Kannst du dir darauf einen Reim machen? Oder hat es vielleicht einen anderen Grund, wieso bei meinen Tests immer der Zeitraum des System-Strats raus kommt?

time_since_epoch
Einen Double willst du für so einen langen Zeitraum für Nanosekunden auch gar nicht haben, wenn du mal darüber nachdenkst wie viele Stellen dieser Zahl durch einen Double schon gar nicht mehr dargestellt werden könnten. Ein int64 ist da schon ganz richtig gewählt.

Ok? Der double Datentyp hat doch eine Genauigkeit von 15 Stellen? Damit müsste man ja sogar 10 Tage Laufzeit des Systemes in Nanosekunden darstellen können.
bei einigen Beispielen, die ich jetzt gefunden habe, wurde das ganz in etwa so angegangen:

Quellcode

1
2
3
chrono::duration<double> timemark = chrono::high_resolution_clock::now().time_since_epoch();
    double durationInSecounds = timemark.count();
    cout << durationInSecounds << endl;

In diesem Fall liefert ja das duration-Objekt über die Methode count ja gleich einen double zurück.
Foglich müsste das ja mit einem double auch irgendwie sinnvoll dargestellt werden können?

Aber vielleicht habe ich deinen Einwand jetzt falsch verstanden... :-)

gruss neptun

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

7

21.05.2018, 12:39

Mit „epoch“ ist eigentlich der 1. Januar 1970 gemeint. https://de.wikipedia.org/wiki/Unixzeit
Mit double kann man alle ganzen Zahlen bis §2^{53}-1§ darstellen, danach nicht mehr jede ganze Zahl. Das würde für etwas über 100 Tage in Nanosekunden reichen. Danach bekäme man die Ungenauigkeit ggf. zu spüren. Praktisch gesehen würde es wahrscheinlich trotzdem noch prima funktionieren, denn für deinen Fall brauchst du keine Nanosekundengenauigkeit.

8

21.05.2018, 16:07

Super, danke für die Erklärung David :) :thumbup:
Jetzt muss ich nur noch raus bekommen, wieso mir anstatt des Zeitraumes seit 1970, der Zeitraum seit System-Start ausgegeben wird.

Aber Danke nochmals an der Stelle für eure Unterstützung. :thumbup:

Gruss neptun

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

9

21.05.2018, 16:23

Scheinbar schreibt der C++-Standard gar nicht vor, was die „Epoche“ einer Uhr ist. Das kann der 1. Januar 1970 sein oder die Systemstartzeit oder sonst irgendwas.

10

21.05.2018, 17:01

Scheinbar schreibt der C++-Standard gar nicht vor, was die „Epoche“ einer Uhr ist. Das kann der 1. Januar 1970 sein oder die Systemstartzeit oder sonst irgendwas.

Interessant. Danke für den Hinweis. :)
Ich werde mich auch nochmals dran setzen und versuchen etwas mehr Klarheit in die Sache zu bringen :)

Werbeanzeige