QueryPerformanceCounter() und QueryPerformanceFrequency() Verständnisfrage



  • 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.
    Martin

    So 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.





  • 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.



  • ich nehme alles zurück, die Klasse funktioniert jetzt.



  • Wo soll denn da ein "Timer" sein... die Klasse macht einen Zeitmessung und stellt keinen Timer zur Verfügung...



  • ja das ist richtig. nehme jetzt doch den Timer als Komponente. Eigentlich wollte ich mit dem QPC einen Timer schreiben. Das müsste ja auch gehen?



  • Wei gesagt... es geht nicht. nur wenn DU Busy-Wait machst, aber dann bruachst Du sowieso keinen Timer mehr, da Deine CPU zu 100% ausgelastet ist.. und wenn Du in Deinem Busy-Wait denkst, Du könntest ein Sleep(>0) einbauen, dann kannst Du gleich einen Windows-Timer nehmen....


Anmelden zum Antworten