AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Windows Thread-Performance wenn minimiert
Thema durchsuchen
Ansicht
Themen-Optionen

Windows Thread-Performance wenn minimiert

Ein Thema von BigAl · begonnen am 12. Sep 2022 · letzter Beitrag vom 5. Okt 2022
Antwort Antwort
Seite 1 von 4  1 23     Letzte »    
BigAl

Registriert seit: 6. Sep 2008
Ort: Kehl
495 Beiträge
 
Delphi 12 Athens
 
#1

Windows Thread-Performance wenn minimiert

  Alt 12. Sep 2022, 06:57
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:
      
  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;
Wobei RoundTime wie folgt implementiert ist:
Delphi-Quellcode:
  function RoundTime(ATime: TDateTime; AToMS: Integer): TDateTime; inline;
  var
    RoundTarget: TDateTime;
  begin
    RoundTarget := SecsPerDay * (1000 / AToMS);
    Result := Round(ATime * RoundTarget) / RoundTarget;
  end;
Ich habe auch schon zum Test die Priorität der Thread bis auf "Time Critical" hochgesetzt. Ändert nichts.

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...
Man sollte nie so viel zu tun haben, dass man zum Nachdenken keine Zeit mehr hat. (G.C. Lichtenberg)

Geändert von BigAl (12. Sep 2022 um 07:20 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke
Online

Registriert seit: 10. Jun 2003
Ort: Berlin
9.345 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: Windows Thread-Performance wenn minimiert

  Alt 12. Sep 2022, 07:40
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.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
BigAl

Registriert seit: 6. Sep 2008
Ort: Kehl
495 Beiträge
 
Delphi 12 Athens
 
#3

AW: Windows Thread-Performance wenn minimiert

  Alt 12. Sep 2022, 07:58
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.
Hallo Jaenicke,

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...
Man sollte nie so viel zu tun haben, dass man zum Nachdenken keine Zeit mehr hat. (G.C. Lichtenberg)
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.110 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: Windows Thread-Performance wenn minimiert

  Alt 12. Sep 2022, 08:12
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:

https://docs.microsoft.com/en-us/win...riority-boosts
  Mit Zitat antworten Zitat
BigAl

Registriert seit: 6. Sep 2008
Ort: Kehl
495 Beiträge
 
Delphi 12 Athens
 
#5

AW: Windows Thread-Performance wenn minimiert

  Alt 12. Sep 2022, 08:25
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:

https://docs.microsoft.com/en-us/win...riority-boosts
Ok. Das schaue ich mir mal genauer an. Grundsätzlich gibt es ja Möglichkeiten. Es können ja z.B. auch Audio oder Videodaten im Hintergrund aufgezeichnet werden, was zeitkritischer ist. Allerdings muss ich halt Aufwand/Nutzen abwägen. Und wie gesagt: Mit Reaktion < 100ms ist es kein Problem (was derzeit gegeben ist). Ich muss mir das mal auf dem "schwachbrüstigeren" Zielsystem anschauen. Normalerweise läuft die Anwendung auch im Vordergrund. Allerdings haben wir Kunden die gerne auch mal die Rechner Dinge missbrauchen, was sie eigentlich nicht dürfen...
Man sollte nie so viel zu tun haben, dass man zum Nachdenken keine Zeit mehr hat. (G.C. Lichtenberg)
  Mit Zitat antworten Zitat
Benutzerbild von Sinspin
Sinspin

Registriert seit: 15. Sep 2008
Ort: Dubai
614 Beiträge
 
Delphi 10.3 Rio
 
#6

AW: Windows Thread-Performance wenn minimiert

  Alt 12. Sep 2022, 10:26
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.
Stefan
Nur die Besten sterben jung
A constant is a constant until it change.
  Mit Zitat antworten Zitat
BigAl

Registriert seit: 6. Sep 2008
Ort: Kehl
495 Beiträge
 
Delphi 12 Athens
 
#7

AW: Windows Thread-Performance wenn minimiert

  Alt 12. Sep 2022, 10:34
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...
Man sollte nie so viel zu tun haben, dass man zum Nachdenken keine Zeit mehr hat. (G.C. Lichtenberg)

Geändert von BigAl (12. Sep 2022 um 10:38 Uhr)
  Mit Zitat antworten Zitat
Edelfix

Registriert seit: 6. Feb 2015
Ort: Stadtoldendorf
213 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: Windows Thread-Performance wenn minimiert

  Alt 12. Sep 2022, 10:43
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.

Geändert von Edelfix (12. Sep 2022 um 10:46 Uhr)
  Mit Zitat antworten Zitat
BigAl

Registriert seit: 6. Sep 2008
Ort: Kehl
495 Beiträge
 
Delphi 12 Athens
 
#9

AW: Windows Thread-Performance wenn minimiert

  Alt 12. Sep 2022, 10:45
Ich vermute das der Thread in Priorität eine Stufe herb gesetzt wird sobald die Anwendung nicht den Focus hat.

Das die Anwendung die im Vordergrund ist hat immer die höhere Priorität.

Kannst das ausprobieren mit zwei gleichen Anwendungen und eine davon im Vordergund. Dann sollte diese schneller sein.
Das mit dem Fokus war auch mein erster Gedanke. Allerdings merke ich erst einen Verlangsamung wenn ich die Anwendung minimiere. Lass ich das Fenster offen und lege eine andere Anwendung in den Vordergrund bleibt die Genauigkeit...
Man sollte nie so viel zu tun haben, dass man zum Nachdenken keine Zeit mehr hat. (G.C. Lichtenberg)
  Mit Zitat antworten Zitat
BigAl

Registriert seit: 6. Sep 2008
Ort: Kehl
495 Beiträge
 
Delphi 12 Athens
 
#10

AW: Windows Thread-Performance wenn minimiert

  Alt 12. Sep 2022, 11:16
Also: Habe mal Now etwas näher analysiert. Die Auflösung ist - meiner Meinung nach - 1 ms:

Delphi-Quellcode:
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.
Als Ergebnis erhalte ich z.B.:
Code:
    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
Warum wird überall (z.B. SO) behauptet die Auflösung sei bestenfalls 16ms, eher 20ms???
Man sollte nie so viel zu tun haben, dass man zum Nachdenken keine Zeit mehr hat. (G.C. Lichtenberg)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 4  1 23     Letzte »    


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:41 Uhr.
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