Thread CPU Auslastung bei genauem Timing



  • Hallo zusammen,

    Ich hab ein kleines Problemchen mit meinem Thread.

    Und zwar wurde ich gerne den Thead in einer 500µs Schleife durchlaufen lassen. Dabei bekomme ich aber einige Auslastungsprobleme.

    double TCanServerBasis::GetCPUTime(void)
    {
    	LARGE_INTEGER Freq;
    	BOOL OK=QueryPerformanceFrequency(&Freq );  // Read Help for MultiProzessor-Machines !
    	LARGE_INTEGER T1;
    	QueryPerformanceCounter( &T1 );
    	double ret=(double)T1.QuadPart/Freq.QuadPart*1000000;
    	return ret;
    }
    
    void __fastcall TCanServerBasis::Execute()
    {
    	double neuzeit;
    	double altzeit=GetCPUTime();
    	this->Priority=tpHighest;
    
    	while(!Terminated)
    	{
    		neuzeit=GetCPUTime();
    		if(neuzeit-altzeit >500)
    		{
                               ... // Was auch immer ausgeführt werden soll
                               ... // unter anderem auch ein paar synchronize mit der Main Form
                             altzeit=neuzeit;
                      }
             }
    }
    

    So bekomm ich zwar ein recht genaues Timing hin, aber meine CPU läuft auf Volllast.

    Wenn ich mit Sleep arbeite bekomm ich zwar die CPU last nach unten aber ich bekomme keine kleinere Zeiten als 1ms hin und zudem habe ich festgestellt das bei unterschiedlichen PCs die Zeit extrem variiert. (zwischen 5 und 200ms)

    100%ig muss die Zeit nicht stimmen, aber wenn zwichen PC 1 und PC 2 schon 200ms liegen das ist das doch etwas zuviel.

    Irgendweine Idee wie ich das Timing hin gekomme ohne die CPU mit 100% zu beanspruchen?

    Danke schonmal



  • Ich vermute mal, Multimedia-Timer, High-Resolution-Timer, Auslagerungsdatei ausmachen, SSD einbauen, Prozess- oder Threadpriorität hochsetzen, und wenn alles nichts hilft, einen Treiber schreiben und absetzen.



  • volkard schrieb:

    einen Treiber schreiben

    Gibt es auch fertig, kostet allerdings ungefähr soviel wie ein C++ Builder Pro

    z.B.
    http://www.kithara.de



  • Dieser Thread wurde von Moderator/in akari aus dem Forum VCL (C++ Builder) in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Na ja, alleine schon die Verwendung von Synchronize dürfte dir einen gewaltigen Strich durch die Rechnung machen. Hier ist nämlich nicht einmal sicher gestellt, dass ein einziger Synchronize-Aufruf in 500 ms abgearbeitet ist, geschweige denn mehrere.

    Und das der Thread 100 Prozent CPU-Last erzeugt, verwundert auch nicht weiter, da die Schleife permanent prüft, ob die 500 ms verstrichen sind. Sogar ohne weiteren Code führt eine solche Schleife zu 100 Przozent Prozessorlast.

    Ich würde es mal mit WaitForSingleObject und einem entsprechendem Event versuchen. Die Timeout-Zeit in Millisekunden müsstest Du dann jeweils zur Laufzeit neu ermitteln, wenn denn tatsächlich alle 500 ms etwas ausgeführt werden soll (Windows ist allerdings kein Echtzeitbetriebssystem!!). Du kannst ein Dummy-Event nehmen, oder sinnvollerweise die Terminierung über dieses Event einleiten. Damit umgehst Du dann auch die möglichen Probleme, die entstehen können, wenn TThread::Terminated und WaitForSingleObjekt parallel verwendet werden.

    Auf Synchronize solltest Du in diesem Fall auch besser komplett verzichten (macht eh keinen Sinn, dass mehrfach die Sekunde aufzurufen, da das viel zu viel Zeit verbrät) und den Datenaustausch zB über nicht blockierende Nachrichten zu machen. Das ist meiner Meinung nach die schnellste Methode (aus Sicht des Threads).



  • Benutze mehr threadyheadies



  • wenn das Timing so wichtig ist, muss du eine Hardware Interrupt programmieren (ring 0) - damit kann man, zumindest mit neuerer Hardware, auch im µs-Bereich Auflösen.


Anmelden zum Antworten