Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Threadproblem - sleep(1) braucht ca. 5 ms! Warum ? (https://www.delphipraxis.net/117449-threadproblem-sleep-1-braucht-ca-5-ms-warum.html)

Andy386 18. Jul 2008 10:18


Threadproblem - sleep(1) braucht ca. 5 ms! Warum ?
 
Hallo,

ich habe mittlerweile ein grösseres Programm "fertig", mit einigen Threads. Einer holt Daten von der Messkarte, einer überprüft auf Eingaben , einer macht Datenauswertung und ein anderer Datenausgabe.
Ist also alles recht übersichtlich, objektorientiert, threadgelagert usw.
DatenHolen hat Prio mittel (z.Zt. kein sleep), Eingabe mittel (mit grösserem sleep), Auswertung mittel (mit sleep) und Ausgabe low (mit kleinem sleep)

Nun mein Problem: Der DatenHol-Thread braucht 1.3 ms für einen Durchlauf. Das ist soweit OK, er könnte auch etwas langsamer sein. Er muss sogar etwas langsamer sein, da der Ausgabethread fast nie dran kommt. Ich dachte dabei an ein sleep(1).
Aber damit braucht er nicht die (im Kopf :) errechneten 2.3 ms, sondern etwas über 7 ms ! Das ist wieder zu langsam...

Ich denke am dll-Aufruf vom sleep wird es nicht liegen, da der Thread mit einem sleep(0) auch nur etwas um 1.3ms braucht.
Ich bin echt kurz vor dem Verzweifeln: Alles fertig, und jetzt kann ich den einen nicht vom Prozessorkern vertreiben !

Hat jemand von euch Erfahrung mit dem Problem, kennt eine Alternative oder hat vielleicht sogar eine sleep(1)-dll ?

Vielen Dank schon mal im Vorraus !

Apollonius 18. Jul 2008 10:37

Re: Threadproblem - sleep(1) braucht ca. 5 ms! Warum ?
 
Du verwendest Windows. Kein System, das für zeitkritische Anwendungen ausgelegt ist. Das ist mit präemptivem Multitasting auch nicht möglich.
Die einzige Lösung ist folglich, das Design zu ändern.

himitsu 18. Jul 2008 10:39

Re: Threadproblem - sleep(1) braucht ca. 5 ms! Warum ?
 
siehe Zitat:
http://www.delphipraxis.net/internal...=668766#668766

Sleep verwendet intern GetTickCount und dieses bietet keine millisekundengenauen Zeitwert.

Lossy eX 18. Jul 2008 10:43

Re: Threadproblem - sleep(1) braucht ca. 5 ms! Warum ?
 
Das Sleep gibt die Ausführung des Threads an den Windows Scheduler ab. Ich hatte vor einer Zeit mal gemessen wie lange ein sleep(1) wirklich braucht und dort kamen Werte von 0.95 bis 1.95 raus. Allerdings hatte mein System auch überhaupt keine Last! Ich vermute fast, dass bei deinem System dann aber gerade etwas gemacht wird und der Thread dann vom Sheduler nach hinten gestellt wird. Dann dauerts länger als 1 Millisekunde. Bei einem Sleep(0) wird der Scheduler "angewiesen" zu schauen ob jemand anderes auch etwas machen will. Wenn dies nicht der Fall ist, dann kehrt der Sleep Befehl sofort zurück anderenfalls kann auch dieser 2-3 Millisekunden dauern.

Ich denke es könnte schon helfen, wenn du die Priorität des Threads um eine oder zwei Stufen erhöhst. Denn dann wird der Scheduler deinen Messthread nicht hinter andere Stellen. Allerdings sollte so etwas sehr gut überlegt sein!

Wobei sich mir die Frage stellt worauf legst du da Priorität. Beim Daten messen (also, dass immer im selben Zeitabstand gemessen wird)? Oder müssen die Daten auch immer sofort ausgewertet werden? Also die gemessen ergebnisse dürften nicht gecacht werden, weil das keinen Sinn machen würde.

Denn wenn du die Daten Messen und sofort auswerten musst könntest du dir evtl einen Thread sparen. Wenn es "egal" ist, wann die Daten ausgewertet werden, dann liegt die Prio ja ganz klar beim Messen. Evtl könntest du auch etwas anderes zum Warten benutzen. So etwas wie Events (nicht TNotifyEvent) warten bis ein Timeout eintrifft oder das Event gesetzt wird. Das könnte auch schon nach 0.5 Millisekunden der Fall sein. Halt wann der Gegenpart das Event setzt.

Andy386 18. Jul 2008 11:03

Re: Threadproblem - sleep(1) braucht ca. 5 ms! Warum ?
 
@Lossy eX
Vielen Dank für die Vorschläge !
Der Anzeige-Thread ist halt nicht so wichtig, wenn ich den erhöhe, ist er gleich mit den anderen, d.h. wenn man viel anzeigen will (oder etwas neues), gehen die anderen mit in die Knie. Das ist aber nicht das gewünschte, da die Daten von der Karte extrem schnell kommen (und dann vom DatenHolenThread (nach Treiberaufruf) gleich gecacht werden). Der Auswerte kann auch noch langsamer sein, der hat an einigen Stellen bereits ein paar Sleeps bekommen, aber das nützt dem Ausgabethread nix, da der DatenHol-Problem-thread nie ein sleep hat...

wie macht man das mit den Events ? Bin noch Delphi-noob :gruebel:


Zitat:

Zitat von himitsu
If you need a higher resolution timer, use a multimedia timer or a high-resolution timer.

Ah, da ist ja ein Ansatz...
Einen solchen timer habe ich schon gemacht/kopiert (um die genaue Threadlaufzeit zu ermitteln...), hab nicht dran gedacht, dass sleep den selben langsamen Timer nimmt wie now & Co.

Aber... habe ich dann viel gekonnt, wenn ich so was wie
Delphi-Quellcode:
jetzt:=now_genau;
while now_genau < (jetzt+1) do
     sysutils.sleep(0);
     //bzw.: Application.ProcessMessages;
nehme, ich mein, dann hat ja der Thread permanent zu tun mit Zeit berechnen...

Oder nützt es was, dass als niederprioren Thread zu machen, der einen interrupt wirft ? Kann man dass überhaupt in XP/Vista machen? Wenn ja, gibt's ein Tutorial für Anfänger dazu ?


[edit] oder vielleicht so:
Delphi-Quellcode:
while now_genau < (jetzt+1) do
begin
     sysutils.sleep(0);
     sysutils.sleep(0);
     sysutils.sleep(0);
     sysutils.sleep(0);
     sysutils.sleep(0);
     sysutils.sleep(0);
     sysutils.sleep(0);
     sysutils.sleep(0);
     sysutils.sleep(0);
     sysutils.sleep(0);
     sysutils.sleep(0);
     sysutils.sleep(0);
end;
Sorry, kenn den Befehlt für spoiler nicht !
[/edit]

alzaimar 18. Jul 2008 11:16

Re: Threadproblem - sleep(1) braucht ca. 5 ms! Warum ?
 
Du wirst es imho einfach nicht schaffen, das eine App genau xyz millisekunden wartet.

Wenn Du jedoch absolut konstante Abstände in den Messwerten benötigst, dann musst Du eben etwas rumtricksen (a.k.a. lineare interpolation)
Als ich mich früher damit beschäftigt habe, war es so, das die Messkarte im Rechner die zeitkritischen Messungen für mich übernommen hat.

Andy386 18. Jul 2008 11:39

Re: Threadproblem - sleep(1) braucht ca. 5 ms! Warum ?
 
Achso, darauf lief die Frage hinaus !
Ne, genau gleicher Abstand muss nicht sein, ich will nur etwas Zeit fürs Zeichnen bekommen...

RavenIV 18. Jul 2008 12:02

Re: Threadproblem - sleep(1) braucht ca. 5 ms! Warum ?
 
Zitat:

Zitat von Andy386
Achso, darauf lief die Frage hinaus !
Ne, genau gleicher Abstand muss nicht sein, ich will nur etwas Zeit fürs Zeichnen bekommen...

Also ich würde die Threads nicht zeitgesteuert arbeiten lassen, das ist zu unzuverlässig / ungenau.

Warum pumpst Du die Daten (Messwerte) nicht vom "Messthread" zum "Anzeigethread" per namedPipe (oder sonst was)?
Der Messthread wartet dann, bis der Anzeigethread die Daten verarbeitet hat und wieder Rückmeldung gibt.
Somit bist Du eventgesteuert und auf der sicheren Seite.

3_of_8 18. Jul 2008 12:22

Re: Threadproblem - sleep(1) braucht ca. 5 ms! Warum ?
 
Soweit ich weiß sind Zeitscheiben normalerweise 10ms lang, also 1ms warten geht sowieso nur, wenn man keinen anderen Thread hat, der länger als ein paar Mikrosekunden rechnet.

Wenn man es wirklich exakt haben will, könnte man es mit einer for-Schleife und einem QPC probieren, muss dann aber noch sicherstellen, dass die Anwendung auch auf keinen Fall währenddessen unterbrochen wird. (was nicht geht, außer vielleicht indem man die Threadpriorität auf Runtime setzt, aber auch da wird es wohl nicht in allen Fällen gehen)

negaH 18. Jul 2008 12:26

Re: Threadproblem - sleep(1) braucht ca. 5 ms! Warum ?
 
MMTimer, Multi Media Timer verwenden, der muß exakt sein. Das bedeutet aber auch das deine MMTimer Callback Funktion gewissen kritischen Anforderungen genügen muß.

Gruß Hagen


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:55 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz