![]() |
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 |
AW: Windows Thread-Performance wenn minimiert
Ein "Hintergrund"-Thread läuft doch über den Dispatcher des Main-Threads soweit ich weiß, zumindest unter Windows.
|
AW: Windows Thread-Performance wenn minimiert
Ok. hab eben mal ein paar anderen Maschinen getestet. Auflösung auf älteren Rechner 16ms auf aktuellen 1ms...
|
AW: Windows Thread-Performance wenn minimiert
Noch einmal:
Wie Windows sein Thread-Scheduling macht ist ein Implementierungs-Detail. Das kann sich durch ein kleines Windows-Update ändern (und es hat sich in der Vergangenheit auch mehrmals geändert!), oder abhängig von verwendeten Architektur oder gar CPU-Modell sein. Verlass dich da nicht drauf. Es ist abhängig von der aktuellen PC-Auslastung, welche Anwendung grade im Vordergrund ist (wie du bereits feststellen musstest) und wer weiß was noch. Wenn dir das Standard-Verhalten (Windows macht, was es für das beste hält) nicht reicht, dann musst du schauen, wie sich das über die Windows-API beeinflussen lässt. PS: Ich habe keinen Beleg, aber ich glaube Zeiten im Millisekunden-Bereich und darunter zu messen ist das Hantieren mit Fließkommazahlen nicht die beste Methode. Nimm besser eine
Delphi-Quellcode:
aus
TStopWatch
Delphi-Quellcode:
.
System.Diagnostics
|
AW: Windows Thread-Performance wenn minimiert
Und aufpassen, ob du dein Programm aus Delphi (F9) startest, oder von extern.
Die Delphi-IDE fummelt seit einer Weile am SystemTimeAdjustment rum, so dass solche Timer plötzlich schneller/öfters reagieren. Es gibt mehrere Implementationen von Higher-Resolution-Timers (z.B. im DirectX), aber so lange man nicht an der Kernzuordnung und Priorität der Threads rumfummelt, kann man ganz kleine Intervalle eh vergessen. Es ist möglich seinen Thread auf einen Kern zu begrenzen und wenn man dann noch ALLE anderen aktuellen/zukünftigen Threads ALLER anderern Anwendungen davon ausschließt, dann wäre man dort alleine und hätte theoretisch die volle Zeit zur Verfügung. |
AW: Windows Thread-Performance wenn minimiert
Um was für Daten geht es eigentlich? Es gibt ja auch die Möglichkeit ganz auf einen PC zu verzichten.
Ich hatte für sowas mal einen Raspberry PI laufen. Oder man geht noch weiter runter zum Arduino, der kann auch WiFi, wenn er muss. |
AW: Windows Thread-Performance wenn minimiert
Zitat:
|
AW: Windows Thread-Performance wenn minimiert
Und wie kommen die Daten von der SPS?
ComPort und TCP-Stack haben ja einen Cache, womit es garnicht wichtig wäre, dass es schnell und genau getimet gelesen wird ... so lange man nur insgesamt schneller liest, als der Cache voll läuft. |
AW: Windows Thread-Performance wenn minimiert
Zitat:
|
AW: Windows Thread-Performance wenn minimiert
Zitat:
![]() |
AW: Windows Thread-Performance wenn minimiert
Wie schon gesagt:
Zitat:
![]() |
AW: Windows Thread-Performance wenn minimiert
Man kann auch bei Windows 10 noch einstellen, wie die Performance bei Vordergrund- und Hintergrund-Programmen aufgeteilt werden soll:
This PC -> Properties -> Advanced System Settings -> Advanced -> Performance -> Settings -> Advanced -> Processor Scheduling Dort von "Programs" auf "Background Services" umstellen. Danach sollte die Thread-Performance von Vordergrund und Hintergrundprogrammen gleich sein. So zumindest die Theorie. (Es kann sein, dass man zu dieser Einstellung auch einfacher hinkommt, aber dies ist die, die ich gerade gefunden habe.) |
AW: Windows Thread-Performance wenn minimiert
Die einfache Idee mit [Win] und dann sowas wie "performance", "Thread" oder "Scheduler" funktioniert garnicht :shock:
Hey, es gibt einen Windows Performance Analyser :shock: Google Youtube meint ![]() Wozu brauchen wir da noch AQTime :roll: |
AW: Windows Thread-Performance wenn minimiert
Zitat:
Grüße Dalai |
AW: Windows Thread-Performance wenn minimiert
Zitat:
|
AW: Windows Thread-Performance wenn minimiert
Ist ja vielleicht schon langsam off-topic aber ich habe neue Erkenntnisse:
Das von mir beschriebene Verhalten tritt nur unter Windows 11 auf (auf 5 Maschinen getestet, 2 x Win 11, 3 x Win 10). Bei Windows 10 bleiben die Threads absolut stabil. Und das ganze Unabhängig davon ob die Priorität auf den Anwendungen oder auf die Hintergrundprozesse eingestellt wird. Auch auf dem Zielsystem, welches - auf Wunsch des Kunden - mit Windows 10 ausgeliefert wird. |
AW: Windows Thread-Performance wenn minimiert
Soweit ich weiss hat sich Microsoft bei Win11 damit gebrüstet Vordergundprozessen viel höhere
Priorität zuzuweisen wie bevor - eventuell überschreibt das die Einstellung die vorher diskutiert wurde und macht diese nutzlos. Hast du schon mal versucht die Threadpriorität im Code zu erhöhen? |
AW: Windows Thread-Performance wenn minimiert
Zitat:
|
AW: Windows Thread-Performance wenn minimiert
Zitat:
|
AW: Windows Thread-Performance wenn minimiert
Kann man hier das verhalten einstellen? Für Windows11
PROCESS_POWER_THROTTLING_IGNORE_TIMER_RESOLUTION ![]() Selber habe ich damit noch kein Problem. Habt ihr auf Produktionsanlagen normales Windows10/11 ? Wir nehmen bei Industrieanlagen immer Windows LTSC mit Applocker und UWF Schreibfilter |
AW: Windows Thread-Performance wenn minimiert
Hi, wie kommt ihr an die LTSC Lizenzen ran ? Ich wollte die auch mal für unser Endkunden haben, ging bei MS aber kein weg rein. Gern auch per PM.
|
AW: Windows Thread-Performance wenn minimiert
Eventuell so, wie bei den Embedded-Versionen.
Man muß erstmal viel Geld bezahlen, um in den erlauchten Kreis zu kommen und dann darf man. :freak: :cry: |
AW: Windows Thread-Performance wenn minimiert
Zitat:
|
AW: Windows Thread-Performance wenn minimiert
Zitat:
Offiziellen Embedded Partner kontaktieren. Mitteilen, dass man neu in Embedded einsteigen will und eine Demo des Designers braucht. Die Images laufen dann ca. 180 Tage. Kauflizenzen gibt es dann in Paketen. Früher war das kleinste 10 Lizenzen. Mittlerweise dürften dass 50 oder 100 Lizenzen sein. Sind teilweise etwas billiger als die Retail Lizenzen. Embedded an sich ich nochmals in verschiedene Unterprogramme aufgeteilt. Da kann wirklich nur ein reiner Embedded Software Partner von MS helfen. Ist nur schwer einen zu bekommen, der nicht gleich die Hardware mit verkaufen will. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:37 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