![]() |
Windows Thread-Performance wenn minimiert
Hallo zusammen,
ich habe eine Thread geschrieben, welche Daten in möglichst exakten Abständen loggen soll. Das funktioniert soweit auch ganz gut, solange die Anwendung nicht minimiert ist. Sobald ich die Anwendung minimiere scheint Windows (Windows 11) die Thread zu verlangsamen. Solange die Anwendung nicht minimiert ist (auch wenn sie nicht das obere Fenster ist), dann ist der maximale Fehler bei ca. 1ms. Ist die App minimiert schwankt das ganze bis ca. 70ms. Hier mal der Code aus der Thread:
Delphi-Quellcode:
Wobei RoundTime wie folgt implementiert ist:repeat try // Calculate next log time. LogTime := RoundTime(LogTime + FInterval / MSecsPerDay, FInterval); CurrentTime := Now; MSecsOff := Round((LogTime - CurrentTime) * MSecsPerDay); if Abs(MSecsOff) > FInterval then // Resync... begin LogTime := RoundTime(CurrentTime, FInterval); if LogTime > CurrentTime then MSecsWait := Round((LogTime - CurrentTime) * MSecsPerDay) else MSecsWait := 0; end else MSecsWait := Max(MSecsOff, 0); FEvent.WaitFor(MSecsWait); FEvent.ResetEvent; if Terminated then Break; {$IFDEF DEBUG} CurrentTime := Now; TInterlocked.Exchange(Double(FLogTimeExact), CurrentTime); TInterlocked.Exchange(FMSecsOff, Round((CurrentTime - LogTime) * MSecsPerDay)); {$ENDIF} // Hier werden die Daten geschrieben... except // Fehlerbehandlung end; until Terminated;
Delphi-Quellcode:
Ich habe auch schon zum Test die Priorität der Thread bis auf "Time Critical" hochgesetzt. Ändert nichts.
function RoundTime(ATime: TDateTime; AToMS: Integer): TDateTime; inline;
var RoundTarget: TDateTime; begin RoundTarget := SecsPerDay * (1000 / AToMS); Result := Round(ATime * RoundTarget) / RoundTarget; end; Hat irgendjemand evtl. eine Idee wie man die Thread dazu bringen kann auch bei minimierter Anwendung die Performance beizubehalten? Ich gehe mal davon aus, dass WaitFor (von TSimpleEvent) der Übeltäter ist. Ich hoffe der Beitrag ist im richtigen Unterforum. Da ich aber erstmal davon ausgehe, dass der Hauptverursacher Windows ist, gehe ich davon aus, dass ich hier richtig bin... Ach ja: Ehe eine Diskussion über die Genauigkeit von "Now" startet: Ich weiß, dass die Genauigkeit von Now üblicherweise im Bereich von 16ms oder so liegt. Das erklärt aber nicht das Verhalten... |
AW: Windows Thread-Performance wenn minimiert
Zunächst einmal:
Windows ist kein Echtzeitbetriebssystem. Insofern ist es generell schwierig, ein genaues Timing einzuhalten. Ich würde statt die Anzahl Millisekunden auf das Event zu warten einmal ein Sleep(1) in einer Schleife versuchen, die läuft, bis das Event signalisiert ist. So kannst du testen, ob es an dem WaitFor liegt. Das Event signalisiert dir, ob Daten da sind? Wenn du ein komplettes Beispielprojekt hättest, das das Problem zeigt, kann ich das Problem auch einmal direkt anschauen. Allgemein: Ein Sleep ist in einem Thread kein Problem, da man ja nur den eigenen Thread schlafen legt. Man sollte nur nicht zu lange schlafen und zwischendurch Terminated prüfen, wenn man in einer Schleife länger wartet, damit die Anwendung sauber beendet werden kann. Gegen die Priorisierung der Vordergrundanwendungen an sich kannst du in deiner Anwendung glaube ich nichts machen, denn das ist eine Benutzereinstellung und soll die Benutzererfahrung verbessern. |
AW: Windows Thread-Performance wenn minimiert
Zitat:
danke für eine Antwort! Ja, mir ist schon klar, dass es mit "real time" und Windows immer etwas hakt. Aber ich bewege mich im Bereich von 1 ms, und das ist eigentlich nichts "schnelles" (wobei real time ja erstmal nichts über Geschwindigkeit sondern über Reaktionsverhalten aussagt). Ich hatte das ganze auch schon anders implementiert, mit genauerer Zeitmessung etc. und auch schon mit Sleep-Schleife. Gleiches Resultat: Solange die Anwendung nicht minimiert ist bleibt alles sehr genau (<= 1ms). Im minimierten Zustand klaut sich Windows scheinbar immer Rechenzeit, selbst wenn die Thread als time critical läuft. Mir fallen da auch noch ein paar andere Möglichkeiten ein (z.B. Interrupts...) aber das ist für die vorliegende Anwendung zu aufwändig. Meine geforderte Genauigkeit muss <= 100ms sein. Das ist zwar bei einem max. Fehler von derzeit ca. 60/70ms gegeben, aber das Zielsystem ist nicht zwingend so potent wie mein Entwicklungsrechner... |
AW: Windows Thread-Performance wenn minimiert
Wie gesagt, Windows ist primär ein Client-System mit einer GUI für den Endbenutzer für den Monitor, weniger ein RT-OS.
Dass Windows in seinem Thread-Scheduling die Priorität für Threads und Prozesse herunterfährt die "nicht sichtbar" sind ist bekannt und gewollt. Genauer erklärt und wie sich das steuern lässt findet sich hier: ![]() |
AW: Windows Thread-Performance wenn minimiert
Zitat:
|
AW: Windows Thread-Performance wenn minimiert
Was Du probieren könntest wäre einen Service zu verwenden. Dann ist zumindest der Fall weg das sich der Zeitabstand signifikant ändert wenn der Nutzer am System spielt. Die Aufzeichnung kann auch dann weiter gehen wenn die Anwendung gekillt wird.
Von CPU prioritäten für die Services habe ich aber keine Ahnung. Mein Service macht nur ca alle zwei Stunden mal was. Genau muss das nicht sein. |
AW: Windows Thread-Performance wenn minimiert
Was mich wundert ist, dass unter normalen Umständen (Fenster nicht minimiert) die Schwankung immer maximal bei +/-1 ms ist. Wäre die Auflösung von "Now" (GetLocalTime) bei 16ms - wird zumindest überall behauptet - dann müsste ich doch immer ein Vielfaches von 16ms als Schwankung erhalten. Tatsächlich bewegt sich das aber immer im Bereich +/-1 ms.
Wo habe ich da den Denkfehler??? Ich habe das ganze auch eben mal mit TStopwatch gegengeprüft. Der Fehler ist bei normaler Ausführung nie größer als 1ms... |
AW: Windows Thread-Performance wenn minimiert
Ich vermute das der Thread in Priorität eine Stufe herb gesetzt wird sobald die Anwendung nicht den Focus hat.
Dass die Anwendung die im Vordergrund ist hat immer die höhere Priorität. Kannst das ausprobieren mit zwei gleichen Anwendungen und eine davon im Vordergrund. Dann sollte diese schneller sein. Früher konnte ich einen Download beschleunigen, wenn ich die Anwendung mit dem Download im Vordergrund gehalten habe. Es ist aber nur ein minimaler Unterschied. |
AW: Windows Thread-Performance wenn minimiert
Zitat:
|
AW: Windows Thread-Performance wenn minimiert
Also: Habe mal Now etwas näher analysiert. Die Auflösung ist - meiner Meinung nach - 1 ms:
Delphi-Quellcode:
Als Ergebnis erhalte ich z.B.:
var
OldTime: TDateTime = 0.0; OldTick: UInt64; Times: TArray<TDateTime>; begin try OldTick := GetTickCount64; repeat if Now <> OldTime then begin Times := Times + [Now]; OldTime := Now; end; until GetTickCount64 > OldTick + 20; WriteLn; for var I := Low(Times) to High(Times) do WriteLn(I:5, ' = ', FormatDateTime('hh:nn:ss.zzz', Times[I])); ReadLn; except on E: Exception do WriteLn(E.ClassName, ': ', E.Message); end; end.
Code:
Warum wird überall (z.B. SO) behauptet die Auflösung sei bestenfalls 16ms, eher 20ms???
0 = 12:14:49.512
1 = 12:14:49.513 2 = 12:14:49.514 3 = 12:14:49.515 4 = 12:14:49.516 5 = 12:14:49.517 6 = 12:14:49.518 7 = 12:14:49.519 8 = 12:14:49.520 9 = 12:14:49.521 10 = 12:14:49.522 11 = 12:14:49.523 12 = 12:14:49.524 13 = 12:14:49.525 14 = 12:14:49.526 15 = 12:14:49.527 16 = 12:14:49.528 17 = 12:14:49.529 18 = 12:14:49.530 19 = 12:14:49.531 20 = 12:14:49.532 21 = 12:14:49.533 22 = 12:14:49.534 23 = 12:14:49.535 24 = 12:14:49.536 25 = 12:14:49.537 |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:12 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-2025 by Thomas Breitkreuz