Zeitmessung mittels QueryPerformanceCounter
-
Hallo zusammen,
ich programmiere mit dem Borland C++ Builder 6.
In meiner Applikation gibt der Nutzer eine bestimmte Rechenzeit in Sekunden an und schickt dann durch einen geeigneten Befehl einen Algorithmus ins Rennen. Dieser wird dann solange Durchlaufen, bis die verstrichene Zeit von Anfang bis jetzt kleiner als die angegebenen Rechenezeit ist.
Dem Nutzer wird dann über eine CGauge (Fortschrittsbalken) und einem Label darüber informiert, wie lange die Berechnung noch andauert.
Um eine möglichst genaue Zeitmessung zu erreichen möchte ich einen QueryPerformanceCounter einsetzen. Leider weiß ich nicht so recht wie ich das anstellen soll.
//--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "Unit1.h" #include "windows.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { int rechenzeit = 60; CGauge1->MaxValue = rechenzeit; //startzeit = jetzt; while (jetzt - startzeit < rechenzeit) { //CGauge1->Progress = jetzt - startzeit; ***Integer-Wert*** //Label->Caption = "Berechnung abgeschlossen in " + IntToStr(jetzt - startzeit) + " Sekunden."; } } //---------------------------------------------------------------------------
Wie kann ich denn dies mit der angesprochenen Funktion realisieren?
Bin für jede Antwort dankbar.
Liebe Grüße
Todd
-
Bei solchen Dingen ist es am einfachsten die Win32-Referenz zu bemühen.
Aber generell geht es so:LARGE_INTEGER jetzt,pc_freq; QueryPerformanceCounter(&jetzt); QueryPerformanceFrequency(&pc_freq); int verstrichene_sekunden=(jetzt.QuadPart-startzeit.QuadPart)/pc_freq.QuadPart;
-
Danke für die schnelle Antwort.
Ich habe es jetzt so realisiert.
LARGE_INTEGER jetzt, startzeit, pc_freq; int rechenzeit = 20; int verstrichene_sekunden = 0; CGauge1->MaxValue = rechenzeit; CGauge1->Visible = true; cw->Enabled = false; QueryPerformanceCounter(&startzeit); while (verstrichene_sekunden < rechenzeit) { QueryPerformanceCounter(&jetzt); QueryPerformanceFrequency(&pc_freq); verstrichene_sekunden=(jetzt.QuadPart-startzeit.QuadPart)/pc_freq.QuadPart; Label4->Caption = "Berechnung abgeschlossen in " + IntToStr(rechenzeit - verstrichene_sekunden) +" Sekunden."; CGauge1->Progress = verstrichene_sekunden; Application->ProcessMessages(); }
Gibt es daran noch was zu verbessern?
Liebe Grüße
Todd
-
Sieht in Ordnung aus, QueryPerformanceFrequency musst du allerdings nur einmal außerhalb der Schleife aufrufen, denn die Frequenz des Counters wird sich nicht ändern.
-
Danke.
Ich werde es gleich beheben.
LG
Todd
-
PerformanceCounter sind nicht auf jedem system verfügbar. sind imho auch leicht overkill. reicht GetTickCount() nicht?
-
Hallo,
ich möchte den QueryPerformanceCounter deshalb benutzen, weil er die größte Genauigkeit hat. (Denke ich jedenfalls)
Von welchen Systemen sprichst du?
Wo könnten Probleme entstehen.Da fällt mir auch noch eine andere Frage ein:
Kann ich mir auch den zeitlichen Unterscheid von (s.o.) startzeit und jetzt in einer höhreren Genauigkeit als in der Einheit Sekunde ausgeben lassen?
Ich denke da an 1/10 bzw. 1/100 Sekunden?Danke im Voraus
LG
Todd
-
GetTickCount()
timeGetTime()
-
Sieht in Ordnung aus, QueryPerformanceFrequency musst du allerdings nur einmal außerhalb der Schleife aufrufen, denn die Frequenz des Counters wird sich nicht ändern.
Was passiert denn, wenn die CPU ihre Taktfrequenz ändert?
(Oder hat das damit nichts zu tun?)
-
Hallo,
jetzt ist die Verwirrung komplett...
Zwei Stühle drei Meinungen...
Mir wurde der QueryPerformanceCounter empfohlen, weil er eine hohe Genauigkeit hat und zudem schnell arbeitet.
Würde ihn auch gerne weiterbenutzen, weil ich die Funktion schon geschrieben habe.
Kann ja auch weiterhin den Befehl "QueryPerformanceCounter(&pc_freq)" innerhalb der Schleife lassen.Kann man denn mit dem QueryPerformanceCounter Zeitunterschiede < 1 Sec berechnen?
Danke und Liebe Grüße
Todd
-
Todd schrieb:
Hallo,
jetzt ist die Verwirrung komplett...
Zwei Stühle drei Meinungen...
Aaalso:
Todd schrieb:
Mir wurde der QueryPerformanceCounter empfohlen, weil er eine hohe Genauigkeit hat und zudem schnell arbeitet.
Yep, bietet (IMHO) die höchste Genauigkeit, die Dir auf Win-Systemen zur Verfügung steht.
Todd schrieb:
Würde ihn auch gerne weiterbenutzen, weil ich die Funktion schon geschrieben habe.
Kann ja auch weiterhin den Befehl "QueryPerformanceCounter(&pc_freq)" innerhalb der Schleife lassen.Kannst Du auch machen, auf neueren Systemen ist das auch eigentlich standardmäßig verfügbar. Soweit ich weiß, arbeitet das über eine eigene Hardware-Einheit auf dem Mainboard, die auf älteren Rechnern schlichtweg noch nicht existierte.
Todd schrieb:
Kann man denn mit dem QueryPerformanceCounter Zeitunterschiede < 1 Sec berechnen?
Klar, aber dafür kannst Du auch GetTickCount, SetTimer oder timeSetEvent (siehe jeweils MSDN) verwenden.
PS: Du solltest allerdings darüber nachdenken, vorher zu prüfen, ob der verwendete Timer bzw. deren Auflösung verfügbar ist (-> sauberer Programmierstil). Dazu stehen entsprechende Informationen ebenfalls in der MSDN
.
-
Todd schrieb:
Kann man denn mit dem QueryPerformanceCounter Zeitunterschiede < 1 Sec berechnen?
ja. aber du brauchst keine performancecounter. du willst halbe ewigkeiten messen, dafür ist GetTickCount() mehr als ausreichend. performancecounter nimmt man, wenn man *extrem* kurze zeitabstände messen will, im bereich von vielleicht 1/30000000 sekunden.
GetTickCount liefert millisekunden, also 1/1000 sekunden, das reicht für deine zwecke absolut aus.
-
@cpt. obvious: Habsch doch schon geschrieben
?!
-
Siehe auch meine Kommentare in den Threads:
http://www.c-plusplus.net/forum/viewtopic-var-t-is-197340-and-highlight-is-.html
http://www.c-plusplus.net/forum/viewtopic-var-t-is-195594-and-highlight-is-.htmlJust my 5 Cents,
Martin