Wie erhalte ich die Dauer als int milli und float Sekunden von <chrono>?

92

Ich versuche, die Chronobibliothek für Timer und Dauer zu verwenden.

Ich möchte in der Lage sein, eine Duration frameStart;(von App-Start) und eine Duration frameDelta;(Zeit zwischen Frames) zu haben.

Ich muss in der Lage sein, die frameDeltaDauer als Millisekunden und Float-Sekunden zu erhalten.

Wie geht das mit den neuen c ++ 11- <chrono>Bibliotheken? Ich habe daran gearbeitet und gegoogelt (Informationen sind spärlich). Der Code ist stark mit Vorlagen versehen und erfordert spezielle Besetzungen und Dinge. Ich kann nicht herausfinden, wie diese Bibliothek richtig verwendet wird.

EddieV223
quelle
Weisen Sie die Dauer einer Dauer mit einem Verhältnis von Sekunden (oder Millisekunden) zu und rufen Sie countsie dann auf ...
K-ballo
Auto Delta = Duration_cast <Sekunden> (FrameDelta) .count (); So was? Es kehrt lange lange kein Schwimmer zurück.
EddieV223
3
@ K-ballo: Wenn die Dauer eine höhere Auflösung hat als der Typ, dem Sie sie zuweisen, ist die Zuordnung schlecht geformt, um Präzisionsverluste zu vermeiden. Sie müssen eine Dauer mit einer Gleitkommadarstellung verwenden oderduration_cast
Jonathan Wakely
@ JonathanWakely: Oh, dann habe ich es falsch benutzt! :(
K-Ballo

Antworten:

150

Ist es das, wonach du suchst?

#include <chrono>
#include <iostream>

int main()
{
    typedef std::chrono::high_resolution_clock Time;
    typedef std::chrono::milliseconds ms;
    typedef std::chrono::duration<float> fsec;
    auto t0 = Time::now();
    auto t1 = Time::now();
    fsec fs = t1 - t0;
    ms d = std::chrono::duration_cast<ms>(fs);
    std::cout << fs.count() << "s\n";
    std::cout << d.count() << "ms\n";
}

was für mich druckt:

6.5e-08s
0ms
Howard Hinnant
quelle
2
warum nicht autoauf fsund verwenden d?
TemplateRex
25
@rhalbersma: Verwendung von autowäre in Ordnung für d, als Ergebnis der duration_cast<ms>ist ms. Dies fs autowäre jedoch nicht angemessen, da das Ergebnis von t1-t0einen Typ hat, high_resolution_clock::durationder nicht unbedingt der gleiche Typ ist wie duration<float>. Zum Beispiel auf meinem System ist es duration<long long, nano>. In dieser Zeile findet also eine implizite Konvertierung von integralbasiert nanosecondszu floatbasiert statt seconds, nur weil der Zieltyp mit angegeben ist fsec.
Howard Hinnant
2
Das sind nützliche Informationen. Nur neugierig: Wäre auto fs = std::chrono::duration_cast<fsec>(t1 - t0);pedantischer Overkill?
TemplateRex
@rhalbersma: Das würde genauso gut funktionieren und genau das Gleiche tun. Was bevorzugt werden sollte, ist für mich völlig stilistisch.
Howard Hinnant
2
Beachten Sie, dass in einigen realen Szenarien (z. B. dem ms-Compiler und den Bibliotheken) die 'high_resolution_clock' Zeiten in der Größenordnung von Mikrosekunden verfehlt und dieser Code Nullen ausspuckt
jheriko
19

Erraten Sie, wonach Sie fragen. Ich gehe davon aus, dass Sie im Millisekunden-Frame-Timer nach etwas suchen, das sich wie folgt verhält:

double mticks()
{
    struct timeval tv;
    gettimeofday(&tv, 0);
    return (double) tv.tv_usec / 1000 + tv.tv_sec * 1000;
}

aber verwendet std::chronostattdessen,

double mticks()
{
    typedef std::chrono::high_resolution_clock clock;
    typedef std::chrono::duration<float, std::milli> duration;

    static clock::time_point start = clock::now();
    duration elapsed = clock::now() - start;
    return elapsed.count();
}

Hoffe das hilft.

Billy The Kid
quelle
Willkommen bei Stack Overflow. Es wäre großartig, wenn Sie Ihrem Code zusätzliche Details hinzufügen könnten. Dies würde anderen Menschen helfen, zu verstehen, was Sie erreichen möchten und wie Ihre Lösungen funktionieren. Vielen Dank!
Luís Cruz
Zu Ihrer Information - dies war das KLARSTE und nützlichste Beispiel für die Dutzende, die ich überprüft habe. Vielen Dank, dass Sie die ewig verwirrenden Chronofunktionen nachvollziehbar gemacht haben.
SMGreenfield
15

Ich weiß nicht, was "Millisekunden und Gleitsekunden" bedeutet, aber das sollte Ihnen eine Idee geben:

#include <chrono>
#include <thread>
#include <iostream>

int main()
{
  auto then = std::chrono::system_clock::now();
  std::this_thread::sleep_for(std::chrono::seconds(1));
  auto now = std::chrono::system_clock::now();
  auto dur = now - then;
  typedef std::chrono::duration<float> float_seconds;
  auto secs = std::chrono::duration_cast<float_seconds>(dur);
  std::cout << secs.count() << '\n';
}
Jonathan Wakely
quelle
Ich denke er will das eigentlich countals float?
K-Ballo
1
Das wird am Ende gedruckt. Aber ich wusste nicht, ob er Millisekunden als Ganzzahl oder Millisekunden nach der Sekunde will oder was.
Jonathan Wakely
Ich möchte in der Lage sein, aus einer chrono :: dauer die als int Millisekunden dargestellte Dauer oder Float-Sekunden (Bruchteil einer Sekunde) zu erhalten
EddieV223
Howards Antwort macht genau das
Jonathan Wakely
8

Im AAA-Stil unter Verwendung der explizit eingegebenen Initialisierungssprache :

#include <chrono>
#include <iostream>

int main(){
  auto start = std::chrono::high_resolution_clock::now();
  // Code to time here...
  auto end = std::chrono::high_resolution_clock::now();

  auto dur = end - start;
  auto i_millis = std::chrono::duration_cast<std::chrono::milliseconds>(dur);
  auto f_secs = std::chrono::duration_cast<std::chrono::duration<float>>(dur);
  std::cout << i_millis.count() << '\n';
  std::cout << f_secs.count() << '\n';
}
Chris Drew
quelle