![]() |
Thread Aufrufzeit vom Windows Sheduler
Hallo zusammen,
ich habe 2 relativ schnelle Notebooks (CPU, RAM, SSD usw.), beide Windows 10 (inkl. Anniversary Update). Hardware unterschiedlich. Kann wenn nötig, näher spezifiziert werden. Folgender Code verhält sich unter beiden Rechnern unterschiedlich:
Delphi-Quellcode:
Auf Rechner A wird die Sollzykluszeit von 6ms eingehalten (AktCycle), auf Rechner B wird immer 16ms angezeigt.
unit Unit1;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls; const ttmSecond : Double = 1/(24*60*60*1000); type TCycleThread = class(TThread) protected procedure Execute; override; private StartZyklus : TDateTime; Procedure Zyklus; public SollZykluszeit : Integer; IstZyklusZeit : Double; MinCycle, AktCycle, MaxCycle: Double; ChgEvent: TNotifyEvent; Constructor Create (CreateSuspended : Boolean); Destructor Destroy; override; end; type TForm1 = class(TForm) Label1: TLabel; Label2: TLabel; Timer1: TTimer; Label3: TLabel; procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure Timer1Timer(Sender: TObject); private { Private-Deklarationen } MyThread : TCycleThread; procedure ChangeEvent(Sender: TObject); public { Public-Deklarationen } end; var Form1: TForm1; implementation {$R *.dfm} function Elapsedms(LastTime: TDateTime): Double; begin Result := (Now - LastTime) / ttmSecond; end; procedure TForm1.FormCreate(Sender: TObject); var H : THandle; begin H := GetCurrentProcess(); SetPriorityClass(H, HIGH_PRIORITY_CLASS); MyThread := TCycleThread.Create(True); MyThread.SollZykluszeit := 6; MyThread.ChgEvent := ChangeEvent; MyThread.Start; end; procedure TForm1.FormDestroy(Sender: TObject); begin if Assigned(MyThread) then FreeAndNil(MyThread); end; procedure TForm1.Timer1Timer(Sender: TObject); begin Timer1.Enabled := False; if Assigned(MyThread) then begin Label2.Caption := 'kürzeste Zykluszeit: ' + MyThread.MinCycle.ToString; Label1.Caption := 'Aktuelle Zykluszeit: ' + MyThread.AktCycle.ToString; Label3.Caption := 'längste Zykluszeit: ' + MyThread.MaxCycle.ToString; end; end; procedure TForm1.ChangeEvent(Sender: TObject); begin Timer1.Enabled := True; end; { TCycleThread } constructor TCycleThread.Create(CreateSuspended: Boolean); begin Inherited Create (CreateSuspended); Priority := tpHighest; MinCycle := -1; AktCycle := -1; MaxCycle := -1; end; destructor TCycleThread.Destroy; begin Inherited Destroy; end; procedure TCycleThread.Execute; var Return : LongWord; ThreadHandle : THandle; begin FreeOnTerminate := False; StartZyklus := Now; try while not Terminated do begin ThreadHandle := Self.ThreadID; Return := MsgWaitForMultipleObjects (0, ThreadHandle, False, SollZykluszeit, QS_ALLINPUT); if Return = WAIT_OBJECT_0 then begin end else begin if not Terminated then begin Zyklus; end; end; end; finally end; end; procedure TCycleThread.Zyklus; begin if Terminated then Exit; //Tue irgendwas IstZyklusZeit := (Elapsedms (StartZyklus)); StartZyklus := Now; if (IstZyklusZeit < MinCycle) or (MinCycle = -1) then MinCycle := IstZyklusZeit; AktCycle := IstZyklusZeit; if (IstZyklusZeit > MaxCycle) or (MaxCycle = -1) then MaxCycle := IstZyklusZeit; if Assigned(ChgEvent) then ChgEvent(Self); end; end. Das liegt ja sicherlich am Windows Sheduler oder sehe ich das falsch? Die Frage ist, kann man am Rechner noch irgendwas einstellen, dass Rechner B ein gleiches Zeitverhalten hat wie Rechner A? Ich hoffe ihr könnt mir da weiterhelfen. |
AW: Thread Aufrufzeit vom Windows Sheduler
Du könntest es einmal mit timeBeginPeriod versuchen.
|
AW: Thread Aufrufzeit vom Windows Sheduler
Und was machst du, wenn das Notebooks der Rechner in einen Energiesparmodus schaltet,
oder wenn gerade die Festplatte ausgelastet ist und das System etwas hängt oder wenn grade ein anderes Programm viel Rechenleistung braucht oder ... ? Windows ist nunmal (standardmäßig) kein Echtzeitsystem und man kann einfach niemals für so kleine Zeiteinheiten eine zuverlässige und überall einheitliche Ausführung garantieren. Selbst unter idealen Bedingungen (keine Systemauslastung), muß man mit Abweichungen von bis zu (meistens) 16 bzw. ~20 Millisekunden rechnen. Abgesehn davon, dass Windows jederzeit am Scheduler was ändern. * andere Windows-Version oder Edition (Server- oder UserSystem) * aufgrund unterschiedlicher Hardware (CPU usw.) * unterschiedliche Powerstates * ... |
AW: Thread Aufrufzeit vom Windows Sheduler
Hallo,
@jaenicke: Ich werde mir mal timeBeginPeriod angucken, danke. @himitsu: Ich weiß das Windows kein Echtzeitsystem ist. Auf beiden Rechnern läuft kein Energiesparmodus, Festplatten können sich nicht ausschalten, keine anderen Programme laufen (außer natürlich die ganzen Windows Dienste), Cortana und die ganzen Hintergrund Apps sind alle deaktiviert. Daher wollte ich wissen, ob man an dem Windows Sheduler selber etwas machen könnte (konfigurieren) um mehr Rechenleistung in das eine Programm geben zu können. Der eine Rechner schafft sogar 1ms, wenn ich das einstelle nur merkt man dann natürlich, dass die VCL ziemlich hängt. Das will ich auch gar nicht, mit der 1ms, ich würde nur eben gerne das Verhalten gleich haben. Liegt das jetzt an irgendwelchen Windows Einstellungen oder doch an der Hardware? |
AW: Thread Aufrufzeit vom Windows Sheduler
Zitat:
Sind solche minimalen Differenzen denn überhaupt in irgeindeiner Form für den Nutzer zu erkennen? |
AW: Thread Aufrufzeit vom Windows Sheduler
Der Hintergrund ist, das über eine extra Steckkarte im PC, Werte in dieser Karte < 1ms aktualsiert.
Deswegen möchte ich so schnell wie möglich, diese Werte auslesen und speichern können. Schade, dass man an der Zeitscheibe nicht selber bisschen drehen kann. Aber danke für die Infos. |
AW: Thread Aufrufzeit vom Windows Sheduler
Zitat:
![]() |
AW: Thread Aufrufzeit vom Windows Sheduler
Und diese Karte ist nicht fähig, selbst ein bisschen zu puffern?
|
AW: Thread Aufrufzeit vom Windows Sheduler
Wenn es nicht wirklich um Echtzeit geht, sondern nur um "so schnell wie möglich", dann lass den Thread doch einfach auf Volllast laufen, komplett ohne zu warten. Dann ist halt ab und zu mal kein neuer Datensatz vorhanden und in anderen Fällen evtl. schon Mehrere (falls die Karte buffert).
Auf der anderen Seite ist es doch bei so frequenten Messdaten meistens nicht wirklich erforderlich (bzw. gewünscht) wirklich jeden Datensatz zu erfassen, da man oft ja eh nur irgendeine Form von Mittelwert bilden will. |
AW: Thread Aufrufzeit vom Windows Sheduler
Ja ich will alle Daten haben zum späteren auswerten.
Volllast den Thread laufen lassen kann ich nicht, da das eigentliche Programm noch mehr Threads hat und auch eine Visu. Das soll ja alles weiterhin laufen. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:29 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz