AGB  ·  Datenschutz  ·  Impressum  







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

Thread Aufrufzeit vom Windows Sheduler

Ein Thema von AJ_Oldendorf · begonnen am 16. Nov 2016 · letzter Beitrag vom 20. Nov 2016
Antwort Antwort
Seite 1 von 2  1 2      
AJ_Oldendorf

Registriert seit: 12. Jun 2009
385 Beiträge
 
Delphi 12 Athens
 
#1

Thread Aufrufzeit vom Windows Sheduler

  Alt 16. Nov 2016, 22:19
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:
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.
Auf Rechner A wird die Sollzykluszeit von 6ms eingehalten (AktCycle), auf Rechner B wird immer 16ms angezeigt.
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.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

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

AW: Thread Aufrufzeit vom Windows Sheduler

  Alt 16. Nov 2016, 23:36
Du könntest es einmal mit timeBeginPeriod versuchen.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.051 Beiträge
 
Delphi 12 Athens
 
#3

AW: Thread Aufrufzeit vom Windows Sheduler

  Alt 17. Nov 2016, 00:57
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
* ...
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu (17. Nov 2016 um 00:59 Uhr)
  Mit Zitat antworten Zitat
AJ_Oldendorf

Registriert seit: 12. Jun 2009
385 Beiträge
 
Delphi 12 Athens
 
#4

AW: Thread Aufrufzeit vom Windows Sheduler

  Alt 17. Nov 2016, 07:38
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?
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#5

AW: Thread Aufrufzeit vom Windows Sheduler

  Alt 17. Nov 2016, 08:13
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?
Kurz und schmerzlos: Vergiss es. Es liegt sowohl an der Hardware, als auch an Windows selbst. Es kann jederzeit ein Interrupt deinen Thread unterbrechen. Außerdem kann die Hardware jederzeit zufällig ein System Management Interrupt auslösen, welcher das komplette System für einige Milisekunden unterbricht. Hierbei bekommt nichtmal Windows selbst mit, dass es unterbrochen wurde.

Sind solche minimalen Differenzen denn überhaupt in irgeindeiner Form für den Nutzer zu erkennen?
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
AJ_Oldendorf

Registriert seit: 12. Jun 2009
385 Beiträge
 
Delphi 12 Athens
 
#6

AW: Thread Aufrufzeit vom Windows Sheduler

  Alt 17. Nov 2016, 08:20
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.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe
Online

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.445 Beiträge
 
Delphi 12 Athens
 
#7

AW: Thread Aufrufzeit vom Windows Sheduler

  Alt 17. Nov 2016, 08:37
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.
Da kann dir verlässlich nur ein Echtzeitsystem helfen - z.B. Kithara.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Der schöne Günther

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

AW: Thread Aufrufzeit vom Windows Sheduler

  Alt 17. Nov 2016, 08:56
Und diese Karte ist nicht fähig, selbst ein bisschen zu puffern?
  Mit Zitat antworten Zitat
Benutzerbild von Zacherl
Zacherl

Registriert seit: 3. Sep 2004
4.629 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#9

AW: Thread Aufrufzeit vom Windows Sheduler

  Alt 17. Nov 2016, 09:02
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.
Projekte:
- GitHub (Profil, zyantific)
- zYan Disassembler Engine ( Zydis Online, Zydis GitHub)
  Mit Zitat antworten Zitat
AJ_Oldendorf

Registriert seit: 12. Jun 2009
385 Beiträge
 
Delphi 12 Athens
 
#10

AW: Thread Aufrufzeit vom Windows Sheduler

  Alt 17. Nov 2016, 09:26
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.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 14:38 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