QueryPerformanceCounter() und QueryPerformanceFrequency() Verständnisfrage
-
ich brauche für mein Programm einen genaueren Timer, der zB alle 1s ein Ereignis auslöst (zB einen Wert speichert)
Da ich den Timer mehrmals brauche will ich ihn in eine Funktion packen. Habe schon ein paar Sachen dazu gelesen aber noch nicht kapiert wie es funzt.was ich weiss das ich die Funktionen QueryPerformanceFrequency() und QueryPerformanceCounter() brauche.
Es soll ein Timer auch für zeitkritische Dinge sein also reicht der normale Timer nicht aus.
-
Es gibt keinen Timer mit QuerPerformance*...
Du solltest die Multimedia-Timer verwenden (time*).
Auch solltest Du beachten, dass Windows kein Echtzeit OS ist...
-
rudpower schrieb:
ich brauche für mein Programm einen genaueren Timer, der zB alle 1s ein Ereignis auslöst
Dafür reicht ein ganz normaler Windows-Timer, hat typischerweise eine Auflösung von ca. 16ms. Das entspricht ca. 62 Timer-Zyklen.
Ansonsten nimm Multimedia-Timer, sie haben eine Auflösung von 1ms, das sind stolze 1000 Zyklen bis zur vollen Sekunde!Die QueryPerformance...-Funktionen sind dafür wirklich oversized, nur meine Meinung. Dazu kommen gewisse Hardware-Abhängigkeiten und leichte Probleme bei Multiprozessor-Systemen!
just my 5 cents,
MartinP.S.: Such mal hier im Forum nach diesen Begriffen...
-
rudpower schrieb:
Es soll ein Timer auch für zeitkritische Dinge sein also reicht der normale Timer nicht aus.
-
Note0r schrieb:
rudpower schrieb:
Es soll ein Timer auch für zeitkritische Dinge sein also reicht der normale Timer nicht aus.
Ja, und? Was willst Du uns damit sagen?
Der Fragesteller hat doch formuliert, daß er alle 1s (also 1 Sekunde!) ein Ereignis feuern möchte.
Das ist in meinen Augen alles andere als zeitkritisch...
-
Mmacher schrieb:
Die QueryPerformance...-Funktionen sind dafür wirklich oversized, nur meine Meinung. Dazu kommen gewisse Hardware-Abhängigkeiten und leichte Probleme bei Multiprozessor-Systemen!
Probleme? Kannst du das mal näher ausführen oder einen Link posten?
-
_matze schrieb:
Mmacher schrieb:
Die QueryPerformance...-Funktionen sind dafür wirklich oversized, nur meine Meinung. Dazu kommen gewisse Hardware-Abhängigkeiten und leichte Probleme bei Multiprozessor-Systemen!
Probleme? Kannst du das mal näher ausführen oder einen Link posten?
Problem???? WO siehst Du denn da eine Möglichkeit einen Timer zu definieren???? Das geht nur mit "Busy-Waiting" was nun mal das schlimmste ist, was Du machen kannst...
-
Jochen Kalmbach schrieb:
_matze schrieb:
Mmacher schrieb:
Die QueryPerformance...-Funktionen sind dafür wirklich oversized, nur meine Meinung. Dazu kommen gewisse Hardware-Abhängigkeiten und leichte Probleme bei Multiprozessor-Systemen!
Probleme? Kannst du das mal näher ausführen oder einen Link posten?
Problem???? WO siehst Du denn da eine Möglichkeit einen Timer zu definieren???? Das geht nur mit "Busy-Waiting" was nun mal das schlimmste ist, was Du machen kannst...
Gehts noch? Ich habe mich darauf bezogen, dass Martin von Problemen bei QueryPerformance... bei Multi-CPU-Systemen gesprochen hat. Vom Timer-selbst-nachbilden habe ich gar nicht gesprochen.
-
Halt, ganz laaangsam....
_matze schrieb:
Mmacher schrieb:
Die QueryPerformance...-Funktionen sind dafür wirklich oversized, nur meine Meinung. Dazu kommen gewisse Hardware-Abhängigkeiten und leichte Probleme bei Multiprozessor-Systemen!
Probleme? Kannst du das mal näher ausführen oder einen Link posten?
Hmmm, einen Link dazu habe ich nicht mehr parat, müßte selbst danach googeln.
Was ich noch in Erinnerung habe ist folgendes:
Es wird angenommen, es handelt sich ein Multi-CPU System (z.B. auf einem Mainboard mit zwei CPU-Sockeln, oft bei Servern (also meistens Xeon-CPUs) anzutreffen.
(Die Betonung liegt auf getrennte CPUs, nicht Multi-Core auf einer CPU!)Wenn ein Thread von der einen CPU auf die andere CPU umgeswitched wird, hat die jeweilige CPU möglicherweise (!) einen anderen Wert für den QueryPerformance-Timerwert. (Zur Erinnerung: Es wird RDTSC von der jeweiligen CPU verwendet)
Kompliziert wird das ganze nämlich dann, wenn aufgrund der Threadverteilung je nach Auslastung (oder auch je nach Systemeinstellungen) mal eine CPU in Sleepmode versetzt wird, wird der RDTSC von der anderen (!) CPU herangezogen.Ich denke, diese (zugegebenermaßen sehr knappe) Formulierung, reicht schon aus, daß man sich ein Bild davon machen kann, daß QueryPerformance-Funktionen nicht soooo problemlos ist, wie viele es behaupten.
Desweiteren gibt es mit einigen AMD-CPUs (ich glaube die Athlons, weiß nicht mehr so genau, auch hier bitte googeln) gewisse Inkompatibilitäten mit RDTSC gibt, wenn das BIOS des Mainboards nicht mitspielt.
Wie gesagt, bei Bedarf darf sich jeder mal danach googeln. Insbesondere in den Blogs einiger Experten wird man darin sicher fündig.
Ich bleibe dabei: Wenn für ein Problem der normale Windows-Timer oder der Multimedia-Timer ausreicht, dann laß lieber die Finger von Queryperformance-Timer! Und das ist bei 1s (wie der Fragesteller möchte) definitiv gegeben.
Martin
-
Da hab ich das falsch verstanden...
Normalerweise gibt es mit QPC keine Probleme... nur bei ganz alten hals:
http://support.microsoft.com/kb/274323/en-us
http://support.microsoft.com/kb/895980/en-us
http://support.microsoft.com/kb/327809/en-us
(und es gibt da noch mehr...)
-
Mmacher schrieb:
Ich bleibe dabei: Wenn für ein Problem der normale Windows-Timer oder der Multimedia-Timer ausreicht, dann laß lieber die Finger von Queryperformance-Timer! Und das ist bei 1s (wie der Fragesteller möchte) definitiv gegeben.
MartinSo kann man das eigentlich nicht sehen... es gibt zwei Verschiedene Dinge "Genauigkeit" und "Zeitraster".
Wenn er ein zeitraster von 1 sec benötigt, sagt dies noch nichts über eine geforderte Genauigkeit aus. Diese hat der OP bisher noch nicht angesprochen...
Es kann ja sein, dass er nur alle Sekunde informiert werden will, dies aber mit einer Geneuigkeit von 1 us. Also genau jede 1000 ms +/- 0,0001 ms
Das geht so mit Windows nicht...
Wenn er sagt, er will 1000 ms (+/- 16 ms), dann geht es mit den Windows-Timern....
Wenn er sagt, er will 1000 ms (+/- 2 ms), dann sollte der die Multimedia-Timer verwenden...
-
wie heisst denn der MultimediaTimer? Ist dies auch eine Komponente? Ich kann nämlich keine finden.
-
Multimedia Timers:
http://msdn.microsoft.com/en-us/library/dd743609(VS.85).aspx
-
ich habe bereits einen Code den ich verwenden soll mit einem QueryPerformanceCounter und Threads. Leider hab ich damit keine Erfahrung und so meine Probleme den Code zu verstehen. Hier der Code:
int i=0; LONGLONG lpFrequency, alt, neu; __fastcall MeinThread::MeinThread(bool CreateSuspended): TThread(CreateSuspended) { QueryPerformanceFrequency((LARGE_INTEGER*)&lpFrequency); Priority = tpHighest; } void __fastcall MeinThread::Execute() { QueryPerformanceCounter((LARGE_INTEGER*)&alt); while(!Terminated) { QueryPerformanceCounter((LARGE_INTEGER*)&neu); if((neu-alt)/(double)lpFrequency >= (0.1*i)) { Synchronize(UpdateCaption); } Sleep(1); } Form1->lAnzeige->Caption = "beendet"; } //--------------------------------------------------------------------------- void __fastcall MeinThread::UpdateCaption() { Form1->lAnzeige->Caption = i++; }
Auch Threads hab ich noch nicht verstanden. Leider fand ich in meinem Buch auch keine Erklärung dazu.
schon die erste Zeile wirft Fragen auf:
QueryPerformanceFrequency((LARGE_INTEGER*)&lpFrequency)
scheinbar handelt es sich hier um eine Funktion. was gibt sie zurück?
-
Mmacher schrieb:
Ja, und? Was willst Du uns damit sagen?
deutsche schwere, lese schwere! aber haben verstandnis!
rudpower schrieb:
ich brauche für mein Programm einen genaueren Timer, der zB alle 1s ein Ereignis auslöst
...
Es soll ein Timer auch für zeitkritische Dinge sein also reicht der normale Timer nicht aus.Er will einen Timer, der zB. alle 1 Sekunden ein Ereignis auslöst.
Es soll aber ein Timer AUCH für zeitkritische Dinge sein.waren diese jetz so schwere verstandnis?
-
rudpower schrieb:
schon die erste Zeile wirft Fragen auf:
QueryPerformanceFrequency((LARGE_INTEGER*)&lpFrequency)
scheinbar handelt es sich hier um eine Funktion. was gibt sie zurück?
Wenn du nicht weißt, was eine Funktion macht, schau einfach in die Doku:
http://msdn.microsoft.com/en-us/library/ms644905(VS.85).aspx
-
gibts die auch in deutsch, die Hilfe ist ja noch kryptischer
-
rudpower schrieb:
gibts die auch in deutsch, die Hilfe ist ja noch kryptischer
Nee, die MS-Hilfe für C und C++ ist nunmal in Englisch. Wenn du da noch Defizite hast, solltest du dringend daran arbeiten. Englisch ist essentiell wichtig für das Programmieren in diesen Sprachen. Du musst zu diesem Zweck auch nicht fließend Unterhaltungen mit englischsprachigen Menschen führen können. Du musst dir nur eine gewisse Fachsprache aneignen. Wenn du ein Wort nicht kennst, schlag es nach, und beim nächsten Mal weißt du Bescheid usw... Das kriegt man schnell drauf.
-
@rudpower:
Wenn Du in Deinem Code ein "Sleep(1)" verwendest, dann kannst Du Dir das aber mitr dem QPC sparen... damit hast Du auch nur eine Auflösung von 10-16 ms...
-
hab das Bsp mal ausprobiert wo die Funktionen in eine Klasse gepackt werden:
class HRTimer { public: HRTimer(void); double getFrequency(void); void startTimer(void) ; double stopTimer(void); private: LARGE_INTEGER start; LARGE_INTEGER stop; double frequency; //.. } HRTimer::HRTimer(void) : frequency(1.0 / this->getFrequency()) { } double HRTimer::GetFrequency(void) { LARGE_INTEGER proc_freq; if (!::QueryPerformanceFrequency(&proc_freq)) throw Exception(TEXT("QueryPerformanceFrequency() failed")); return proc_freq.QuadPart; } void HRTimer::StartTimer(void) { DWORD_PTR oldmask = ::SetThreadAffinityMask(::GetCurrentThread(), 0); ::QueryPerformanceCounter(&start); ::SetThreadAffinityMask(::GetCurrentThread(), oldmask); } double HRTimer::StopTimer(void) { DWORD_PTR oldmask = ::SetThreadAffinityMask(::GetCurrentThread(), 0); ::QueryPerformanceCounter(&stop); ::SetThreadAffinityMask(::GetCurrentThread(), oldmask); return ((stop.QuadPart - start.QuadPart) * frequency); // // Shouldn't you divide by frequency instead of multiply? // }
bekomme prompt Fehlermeldungen, dass der HRTimer hier nicht definiert werden darf.