6 Stimmen

Wie berechnet man die Zeit eines Vorgangs in Mikrosekundengenauigkeit?

Ich möchte die Leistung einer Funktion in Mikrosekundengenauigkeit auf der Windows-Plattform berechnen.

Nun hat Windows selbst eine Millisekunden-Granularität, wie kann ich das also erreichen?

Ich habe das folgende Beispiel ausprobiert, aber keine korrekten Ergebnisse erhalten.

LARGE_INTEGER ticksPerSecond = {0};
LARGE_INTEGER tick_1 = {0};
LARGE_INTEGER tick_2 = {0};
double uSec = 1000000;

// Get the frequency
QueryPerformanceFrequency(&ticksPerSecond);

//Calculate per uSec freq
double uFreq = ticksPerSecond.QuadPart/uSec;

// Get counter b4 start of op
QueryPerformanceCounter(&tick_1);

// The ope itself
Sleep(10);

// Get counter after opfinished
QueryPerformanceCounter(&tick_2);

// And now the op time in uSec
double diff = (tick_2.QuadPart/uFreq) - (tick_1.QuadPart/uFreq);

20voto

Matti Virkkunen Punkte 61148

Führen Sie den Vorgang etwa eine Million Mal in einer Schleife aus und teilen Sie das Ergebnis durch diese Zahl. Auf diese Weise erhalten Sie die durchschnittliche Ausführungszeit über diese Anzahl von Durchläufen. Die Zeitmessung für eine (oder sogar hundert) Ausführungen einer sehr schnellen Operation ist aufgrund von Multitasking und ähnlichem sehr unzuverlässig.

7voto

vicatcu Punkte 5089
  • es kompilieren
  • Sehen Sie sich die Assembler-Ausgabe an
  • Zählen Sie die Anzahl der einzelnen Anweisungen in Ihrer Funktion
  • die Zyklen pro Befehl auf Ihrem Zielprozessor anwenden
  • am Ende eine Zykluszahl erhalten
  • multipliziert mit der Taktfrequenz, mit der Sie arbeiten
  • willkürliche Skalierungsfaktoren anwenden, um Cache-Fehlversuche und falsche Verzweigungsvorhersagen zu berücksichtigen lol

(Mann, für diese Antwort werde ich bestimmt runtergevotet werden)

3voto

Hans Passant Punkte 894572

Nein, Sie erhalten wahrscheinlich ein genaues Ergebnis, QueryPerformanceCounter() funktioniert gut für die Zeitmessung kurzer Intervalle. Was falsch ist, ist Ihre Erwartung an die Genauigkeit von Sleep(). Es hat eine Auflösung von 1 Millisekunde, seine Genauigkeit ist viel schlechter. Nicht besser als etwa 15,625 Millisekunden auf den meisten Windows-Rechnern.

Um sie auch nur annähernd auf 1 Millisekunde zu bringen, müssen Sie die timeBeginPeriod(1) zuerst. Das wird das Spiel wahrscheinlich verbessern, abgesehen von dem Ruckeln, das durch Windows als Multitasking-Betriebssystem entsteht.

0voto

Wim Punkte 10783

Wenn Sie dies für die Offline-Profilerstellung tun, besteht eine sehr einfache Möglichkeit darin, die Funktion 1000 Mal auszuführen, auf die nächste Millisekunde genau zu messen und durch 1000 zu dividieren.

0voto

Thomas Matthews Punkte 54757

Um eine feinere Auflösung als 1 ms zu erhalten, müssen Sie in der Dokumentation Ihres Betriebssystems nachsehen. Möglicherweise gibt es APIs, die eine Zeitauflösung im Mikrosekundenbereich ermöglichen. Wenn dies der Fall ist, lassen Sie Ihre Anwendung mehrmals laufen und ermitteln Sie die Durchschnittswerte.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X