webentwicklung-frage-antwort-db.com.de

Laufzeit eines C++ - Codes messen?

Ich möchte die Laufzeit meines C++ - Codes messen. Die Ausführung meines Codes dauert ungefähr 12 Stunden und ich möchte diese Zeit am Ende der Ausführung meines Codes schreiben. Wie kann ich das in meinem Code tun?

Betriebssystem: Linux

23
peaceman

Wenn Sie C++ 11 verwenden, können Sie system_clock::now() verwenden:

auto start = std::chrono::system_clock::now();

/* do some work */

auto end = std::chrono::system_clock::now();
auto elapsed = end - start;
std::cout << elapsed.count() << '\n';

Sie können auch die Granularität angeben, die zum Darstellen einer Dauer verwendet werden soll:

// this constructs a duration object using milliseconds
auto elapsed =
    std::chrono::duration_cast<std::chrono::milliseconds>(end - start);

// this constructs a duration object using seconds
auto elapsed =
    std::chrono::duration_cast<std::chrono::seconds>(end - start);

Wenn Sie C++ 11 nicht verwenden können, werfen Sie einen Blick auf chrono von Boost.

Das Beste an der Verwendung solcher Standard-Bibliotheken ist, dass ihre Portabilität sehr hoch ist (z. B. funktionieren sie beide unter Linux und Windows). Sie müssen sich also nicht allzu viele Sorgen machen, wenn Sie Ihre Bewerbung anschließend portieren möchten.

Diese Bibliotheken folgen ebenfalls einem modernen C++ - Design, im Gegensatz zu C-ähnlichen Ansätzen.

EDIT: Das obige Beispiel kann verwendet werden, um Wanduhrzeit zu messen. Dies ist jedoch nicht die einzige Möglichkeit, die Ausführungszeit eines Programms zu messen. Erstens können wir zwischen Benutzer- und Systemzeit unterscheiden:

  • Benutzerzeit: Die Zeit, die das Programm in user space verbringt.
  • Systemzeit: Die Zeit, die das Programm im System- (oder Kernel-) Bereich verbracht hat. Ein Programm betritt den Kernel-Space zum Beispiel, wenn ein Systemaufruf ausgeführt wird.

Abhängig von den Zielen kann es erforderlich sein, die Systemzeit als Teil der Ausführungszeit eines Programms zu betrachten. Wenn zum Beispiel nur eine Compiler-Optimierung anhand des Benutzercodes gemessen werden soll, ist es wahrscheinlich besser, die Systemzeit wegzulassen. Wenn der Benutzer andererseits feststellen möchte, ob Systemaufrufe einen erheblichen Overhead darstellen, muss auch die Systemzeit gemessen werden.

Darüber hinaus können, da die meisten modernen Systeme time-shared sind, verschiedene Programme um mehrere Rechenressourcen (z. B. CPU) konkurrieren. In diesem Fall kann eine andere Unterscheidung getroffen werden:

  • Wanduhrzeit : Durch die Verwendung der Wanduhrzeit wird die Ausführung des Programms auf dieselbe Weise gemessen, als würden wir eine externe (Wand-) Uhr verwenden. Dieser Ansatz berücksichtigt nicht die Interaktion zwischen Programmen.
  • CPU time : In diesem Fall zählt nur die Zeit, die ein Programm tatsächlich auf der CPU läuft. Wenn ein Programm (P1) zusammen mit einem anderen Programm (P2) geplant wird und wir die CPU-Zeit für P1 erhalten möchten, umfasst dieser Ansatz nicht die Zeit, während P2 läuft und P1 auf die CPU wartet (im Gegensatz zu Annäherung an die Wanduhrzeit).

Zum Messen der CPU-Zeit enthält Boost einen Satz zusätzlicher Uhren :

  • process_real_cpu_clock erfasst die CPU-Zeit der Wanduhr, die der aktuelle Prozess verbraucht.
  • process_user_cpu_clock erfasst die vom aktuellen Prozess verbrauchte CPU-Zeit des Benutzers.
  • process_system_cpu_clock erfasst die System-CPU-Zeit, die der aktuelle Prozess verbraucht. Eine Tuple-artige Klasse process_cpu_clock, die die realen Prozesszeiten, die Prozessorzeiten der Benutzer- und der System-CPU zusammen erfasst.
  • Eine stationäre Uhr mit thread_clock-Thread, die die Zeit angibt, die der aktuelle Thread verbracht hat (sofern von einer Plattform unterstützt).

Leider verfügt C++ 11 nicht über solche Uhren. Aber Boost ist eine weit verbreitete Bibliothek, und wahrscheinlich werden diese zusätzlichen Uhren irgendwann in C++ 1x integriert. Wenn Sie also Boost verwenden, sind Sie bereit, wenn der neue C++ - Standard sie hinzufügt.

Wenn Sie die Zeit messen möchten, die ein Programm von der Befehlszeile aus ausführt (im Gegensatz zum Hinzufügen von Code zu Ihrem Programm), können Sie sich den Befehl time ansehen, genau wie @ BЈовић dies empfiehlt. Bei diesem Ansatz können Sie jedoch nicht einzelne Teile Ihres Programms messen (z. B. die Zeit, die zum Ausführen einer Funktion benötigt wird).

69
betabandido

Verwenden Sie std::chrono::steady_clock und nicht std::chrono::system_clock , um die Laufzeit in C++ 11 zu messen. Der Grund ist (zitiert die Dokumentation von system_clock):

bei den meisten Systemen kann die Systemzeit jederzeit eingestellt werden

während steady_clock monoton ist und sich besser zum Messen von Intervallen eignet:

Die Klasse std :: chrono :: steady_clock repräsentiert eine monotone Uhr. Die Zeit Die Punkte dieser Uhr können nicht abnehmen, da sich die physische Zeit vorwärts bewegt. Diese Uhr bezieht sich nicht auf die Uhrzeit der Wanduhr und eignet sich am besten für Messintervalle.

Hier ist ein Beispiel:

auto start = std::chrono::steady_clock::now();
// do something
auto finish = std::chrono::steady_clock::now();
double elapsed_seconds = std::chrono::duration_cast<
  std::chrono::duration<double> >(finish - start).count();

Ein kleiner praktischer Tipp: Wenn Sie die Laufzeit messen und Sekunden melden möchten, ist std::chrono::duration_cast<std::chrono::seconds> selten das, was Sie brauchen, weil Sie ganze Sekunden angeben. Um die Zeit in Sekunden als double zu erhalten, verwenden Sie das obige Beispiel.

22
vitaut

Sie können time verwenden, um Ihr Programm zu starten. Wenn es endet, werden schöne Zeitstatistiken zum Programmablauf gedruckt. Es ist einfach zu konfigurieren, was gedruckt werden soll. Standardmäßig werden Benutzer- und CPU-Zeiten gedruckt, die zur Ausführung des Programms erforderlich waren.

BEARBEITEN: Beachten Sie, dass jede Maßnahme aus dem Code nicht korrekt ist, da Ihre Anwendung von anderen Programmen blockiert wird und Sie falsche Werte erhalten*.

* Mit falschen Werten habe ich gemeint, dass es einfach ist, die zum Ausführen des Programms benötigte Zeit zu erhalten, aber diese Zeit hängt von der CPU-Auslastung während der Programmausführung ab. Um eine relativ stabile Zeitmessung zu erhalten, die nicht von der CPU-Last abhängt, können Sie die Anwendung mit time ausführen und die CPU als Messergebnis verwenden.

10
BЈовић

Ich habe so etwas in einem meiner Projekte verwendet:

#include <sys/time.h>

struct timeval start, end;
gettimeofday(&start, NULL);
//Compute
gettimeofday(&end, NULL);
double elapsed = ((end.tv_sec - start.tv_sec) * 1000) 
        + (end.tv_usec / 1000 - start.tv_usec / 1000);

Dies ist für Millisekunden und funktioniert sowohl für C als auch für C++.

9
Kjir

Wenn Sie die gemessene Zeit mit printf () drucken möchten, können Sie dies verwenden:

auto start = std::chrono::system_clock::now();
/* measured work */
auto end = std::chrono::system_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
printf("Time = %lld ms\n", static_cast<long long int>(elapsed.count()));
1
Natan Ayalon

Dies ist der Code, den ich benutze:

  const auto start = std::chrono::steady_clock::now();

  // Your code here.

  const auto end = std::chrono::steady_clock::now();
  std::chrono::duration<double> elapsed = end - start;
  std::cout << "Time in seconds: " << elapsed.count() << '\n';

Du willst nicht std::chrono::system_clock weil es nicht monoton ist! Wenn der Benutzer die Zeit in der Mitte Ihres Codes ändert, ist Ihr Ergebnis falsch - es kann sogar negativ sein. std::chrono::high_resolution_clock kann implementiert werden mit std::chrono::system_clock also würde ich das auch nicht empfehlen.

Dieser Code vermeidet auch hässliche Darstellungen.

0
Timmmm

Sie können auch einige Timer-Klassen ausprobieren, die automatisch gestartet und gestoppt werden, und Statistiken über die durchschnittliche, maximale und minimale Zeit in einem Codeblock sowie die Anzahl der Anrufe sammeln. Diese cxx-rtimer-Klassen sind auf GitHub verfügbar und bieten Unterstützung für die Verwendung von std :: chrono, clock_gettime () oder boost :: posix_time als Back-End-Taktquelle.

Mit diesen Timern können Sie Folgendes tun:

void timeCriticalFunction() {
    static rtimers::cxx11::DefaultTimer timer("expensive");
    auto scopedStartStop = timer.scopedStart();
    // Do something costly...
}

mit Timing-Statistiken, die nach Abschluss des Programms in std :: cerr geschrieben werden.

0
rwp