Ich möchte herausfinden, wie viel Zeit eine bestimmte Funktion in meinem C ++ - Programm benötigt, um unter Linux ausgeführt zu werden . Danach möchte ich einen Geschwindigkeitsvergleich machen. Ich habe mehrere Zeitfunktionen gesehen, aber am Ende hatte ich diese durch Boost. Chrono:
process_user_cpu_clock, captures user-CPU time spent by the current process
Jetzt ist mir nicht klar, ob ich die obige Funktion verwende. Bekomme ich die einzige Zeit, die die CPU für diese Funktion aufgewendet hat?
Zweitens konnte ich kein Beispiel für die Verwendung der obigen Funktion finden. Kann mir bitte jemand helfen, wie man die obige Funktion benutzt?
PS: Im Moment verwende ich std::chrono::system_clock::now()
, um Zeit in Sekunden zu erhalten, aber dies führt zu unterschiedlichen Ergebnissen aufgrund der unterschiedlichen CPU-Auslastung jedes Mal.
quelle
clock_gettime
.. gcc definiert andere Uhren als:typedef system_clock steady_clock; typedef system_clock high_resolution_clock;
unter Windows verwendenQueryPerformanceCounter
.Antworten:
Es ist eine sehr einfach zu verwendende Methode in C ++ 11. Sie müssen
std::chrono::high_resolution_clock
aus dem<chrono>
Header verwenden.Verwenden Sie es so:
Dadurch wird die Dauer der Funktion gemessen.
HINWEIS: Sie erhalten nicht immer das gleiche Timing für eine Funktion. Dies liegt daran, dass die CPU Ihres Computers weniger oder mehr von anderen auf Ihrem Computer ausgeführten Prozessen verwendet werden kann, genauso wie Ihr Geist mehr oder weniger konzentriert sein kann, wenn Sie eine mathematische Übung lösen. Im menschlichen Geist können wir uns an die Lösung eines mathematischen Problems erinnern, aber für einen Computer wird der gleiche Prozess immer etwas Neues sein; So erhalten Sie, wie gesagt, nicht immer das gleiche Ergebnis!
quelle
high_resolution_clock
gibt Ihnen die physische und Echtzeit, die Ihre Funktion benötigt, um ausgeführt zu werden. In Ihrem ersten Lauf wurde Ihre CPU also weniger verbraucht als im nächsten Lauf. Mit "verwendet" meine ich, welche andere Anwendungsarbeit die CPU verwendet.steady_clock
? Ist es nicht möglich, dass eshigh_resolution_clock
sich um eine nicht monotone Uhr handelt?Hier ist eine Funktion, die die Ausführungszeit jeder als Argument übergebenen Funktion misst:
Anwendungsbeispiel:
Ausgabe:
quelle
high_resolution_clock
kann ein Alias vonsystem_clock
(Wanduhr)steady_clock
oder eine dritte unabhängige Uhr sein. Details finden Sie hier . Für CPU-Uhrstd::clock
kann verwendet werdenwindows.h
in einem nicht trivialen c ++ - Projekt enthalten sind. In Bezug aufassert
zunächst: "quod licet iovi non licet Bovi";). Zweitens werden nicht alle Entscheidungen in der Standardbibliothek (manchmal aus Jahrzehnten) nach modernen Maßstäben als gute Idee angesehen. Es gibt einen Grund, warum der Designer von C ++ - Modulen sehr bemüht ist, Makros nicht standardmäßig zu exportieren.einfaches Programm, um eine benötigte Funktionsausführungszeit zu finden.
quelle
In Scott Meyers Buch habe ich ein Beispiel für einen universellen generischen Lambda-Ausdruck gefunden, mit dem die Ausführungszeit von Funktionen gemessen werden kann. (C ++ 14)
Das Problem ist, dass Sie nur eine Ausführung messen, sodass die Ergebnisse sehr unterschiedlich sein können. Um ein zuverlässiges Ergebnis zu erhalten, sollten Sie eine große Anzahl von Ausführungen messen. Laut Andrei Alexandrescu Vortrag auf der Code :: Dive 2015 Konferenz - Schreiben von Fast Code I:
Gemessene Zeit: tm = t + tq + tn + bis
wo:
tm - gemessene (beobachtete) Zeit
t - der tatsächliche Zeitpunkt des Interesses
tq - Zeit, die durch Quantisierungsrauschen hinzugefügt wird
tn - Zeit, die durch verschiedene Geräuschquellen hinzugefügt wird
zu - Overhead-Zeit (Messen, Schleifen, Aufrufen von Funktionen)
Nach dem, was er später in der Vorlesung sagte, sollten Sie ein Minimum dieser großen Anzahl von Ausführungen als Ergebnis nehmen. Ich ermutige Sie, sich die Vorlesung anzusehen, in der er erklärt, warum.
Es gibt auch eine sehr gute Bibliothek von Google - https://github.com/google/benchmark . Diese Bibliothek ist sehr einfach zu bedienen und leistungsstark. Sie können einige Vorträge von Chandler Carruth auf Youtube lesen, wo er diese Bibliothek in der Praxis nutzt. Zum Beispiel CppCon 2017: Chandler Carruth „Going Nowhere Faster“;
Anwendungsbeispiel:
EDIT: Natürlich müssen Sie immer daran denken, dass Ihr Compiler etwas optimieren kann oder nicht. Werkzeuge wie perf können in solchen Fällen nützlich sein.
quelle
Einfacher Weg für älteres C ++ oder C:
Timing-Präzision in Sekunden ist
1.0/CLOCKS_PER_SEC
quelle
Zum Beispiel dauert es ungefähr 1 Minute und 40 Sekunden, um alle Primzahlen zwischen 1 und 100 Millionen zu finden. Die Ausführungszeit wird also wie folgt gedruckt:
Der Code ist hier:
quelle
Hier ist eine hervorragende Klassenvorlage nur für Header, um die verstrichene Zeit einer Funktion oder eines Codeblocks zu messen:
Hier sind einige Verwendungen davon:
Da es sich bei der Klasse um eine Vorlage handelt, können wir ganz einfach festlegen, wie unsere Zeit gemessen und angezeigt werden soll. Dies ist eine sehr praktische Vorlage für Utility-Klassen zum Benchmarking und sehr einfach zu verwenden.
quelle
stop()
Mitgliedsfunktion nicht benötigt, da der Destruktor den Timer für Sie stoppt.test code
den Timer starten. Anschließend verwendentest code
Sie explizit das Timer-Objekt und rufen dessen Stop-Methode auf. Sie müssen es manuell aufrufen, wenn Siestop
den Timer verwenden möchten . Die Klasse akzeptiert keine Parameter. Auch wenn Sie diese Klasse so verwendet haben, wie ich es gezeigt habe, werden Sie feststellen, dass zwischen dem Aufruf vonobj.stop
und seiner Klasse nur eine minimale Zeitspanne vergehtdestructor
.<chrono>
?Ich empfehle die Verwendung,
steady_clock
die im Gegensatz zu monoton garantiert isthigh_resolution_clock
.Ausgabe:
quelle
Sie können eine einfache Klasse haben, die für diese Art von Messungen verwendet werden kann.
Sie müssen lediglich zu Beginn dieser Funktion ein Objekt in Ihrer Funktion erstellen
und das ist es. Die Klasse kann an Ihre Anforderungen angepasst werden.
quelle
Da keine der bereitgestellten Antworten sehr genau ist oder reproduzierbare Ergebnisse liefert, habe ich beschlossen, meinem Code einen Link hinzuzufügen, der eine Genauigkeit von weniger als einer Nanosekunde und wissenschaftliche Statistiken aufweist.
Beachten Sie, dass dies nur zum Messen von Code funktioniert, dessen Ausführung (sehr) kurze Zeit in Anspruch nimmt (auch bekannt als einige Taktzyklen bis zu einigen Tausend): Wenn sie so lange laufen, dass sie wahrscheinlich durch einen -heh- Interrupt unterbrochen werden dann ist es eindeutig nicht möglich, ein reproduzierbares und genaues Ergebnis zu liefern; Die Folge davon ist, dass die Messung niemals beendet wird: Sie misst weiter, bis statistisch zu 99,9% sicher ist, dass sie die richtige Antwort hat, was auf einem Computer, auf dem andere Prozesse ausgeführt werden, niemals geschieht, wenn der Code zu lange dauert.
https://github.com/CarloWood/cwds/blob/master/benchmark.h#L40
quelle
Wenn Sie Zeit und Codezeilen sparen möchten, können Sie die Messung der Funktionsausführungszeit zu einem einzeiligen Makro machen:
a) Implementiere eine Zeitmessklasse wie oben bereits vorgeschlagen (hier ist meine Implementierung für Android):
b) Fügen Sie ein praktisches Makro hinzu, das den aktuellen Funktionsnamen als TAG verwendet (die Verwendung eines Makros ist hier wichtig, andernfalls
__FUNCTION__
wirdMeasureExecutionTime
anstelle der zu messenden Funktion ausgewertetc) Schreiben Sie Ihr Makro am Anfang der Funktion, die Sie messen möchten. Beispiel:
Was zu folgender Ausgabe führt:
Beachten Sie, dass dies (wie alle anderen vorgeschlagenen Lösungen) die Zeit zwischen dem Aufruf Ihrer Funktion und der Rückgabe misst, nicht unbedingt die Zeit, zu der Ihre CPU die Funktion ausgeführt hat. Wenn Sie dem Scheduler jedoch keine Änderung zum Anhalten Ihres laufenden Codes durch Aufrufen von sleep () oder ähnlichem geben, gibt es keinen Unterschied zwischen.
quelle