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
AJ_Oldendorf

Registriert seit: 12. Jun 2009
411 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.869 Beiträge
 
Delphi 12 Athens
 
#2

AW: Thread Aufrufzeit vom Windows Sheduler

  Alt 16. Nov 2016, 23:36
Du könntest es einmal mit timeBeginPeriod versuchen.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.326 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
* ...
Ein Therapeut entspricht 1024 Gigapeut.

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

Registriert seit: 12. Jun 2009
411 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
411 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
t.roller
(Gast)

n/a Beiträge
 
#7

AW: Thread Aufrufzeit vom Windows Sheduler

  Alt 20. Nov 2016, 10:09
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...
Man kann beide Computer mit einem einfachen Programm vergleichen:
ClockRes

Ergebnis:
MAXIMUM TIMER
MINIMUM TIMER
CURRENT TIMER

siehe Anhang.
Angehängte Grafiken
Dateityp: jpg ClockRes.jpg (22,7 KB, 23x aufgerufen)
  Mit Zitat antworten Zitat
t.roller
(Gast)

n/a Beiträge
 
#8

AW: Thread Aufrufzeit vom Windows Sheduler

  Alt 20. Nov 2016, 15:38
SetTimerResolution im Anhang.
Angehängte Grafiken
Dateityp: jpg SetTimerResolution.jpg (22,6 KB, 28x aufgerufen)
Angehängte Dateien
Dateityp: zip TimerResolution.zip (6,5 KB, 12x aufgerufen)
  Mit Zitat antworten Zitat
AJ_Oldendorf

Registriert seit: 12. Jun 2009
411 Beiträge
 
Delphi 12 Athens
 
#9

AW: Thread Aufrufzeit vom Windows Sheduler

  Alt 20. Nov 2016, 21:20
Clockres und settimerresolution gucke ich mir mal an.

Nein die Karte kann nicht puffern.

Ich habe es mit timeBeginPeriod gelöst.
Das scheint gut zu klappen und reicht für meine Zwecke.

Danke nochmals
  Mit Zitat antworten Zitat
Antwort Antwort


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 07:08 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