Delphi-PRAXiS
Seite 3 von 4     123 4      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Problem mit sleep (https://www.delphipraxis.net/130060-problem-mit-sleep.html)

Dunkel 2. Mär 2009 22:38

Re: Problem mit sleep
 
Zitat:

Zitat von himitsu
Wie schon gesagt ... Windows (auch nicht Linux) ist nicht für sehr zeitgenaue und schnelle Sachen ausgelegt.

Ich habe das Zitat korrigiert, könnte sonst verwirren.

Und, Windows ist durchaus auch für RealTime-Processing geeignet. Die ganze Embedded-Reihe ist AFAIK auf RealTime ausgelegt; muss es auch, daran hängen häufig komplexe Maschinen welche zeitkritisch arbeiten müssen/sollen. Linux kann ähnliches. Nur die ganzen EndUser-Editionen sind keinesfalls dafür geeignet (es sei denn man investiert ein paar Euronen), diese sind eher fürs Multitasking optimiert.

Sunlight7 3. Mär 2009 01:34

Re: Problem mit sleep
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich bastele gerade mit D2 an einer präzisions Laufzeitsteuerung und muß festellen, das Windows (XP) sehr wohl im 1 MS Bereich arbeiten kann.

Wers nicht glaub, einfach mal den Anhang ausprobieren.
Is noch nicht fertig, ich bastle wie gesagt gerade dran rum...

hathor 3. Mär 2009 07:51

Re: Problem mit sleep
 
Delphi-Quellcode:
procedure DelayQPC(t: cardinal);
var a, b: Int64;
Begin
    QueryPerformanceFrequency(b); QueryPerformanceCounter(a);
    b := a + (b * t) div 1000000; //10 000 = 0.1ms, 100 000 = 0.01ms, 1 000 000 = 0.001ms
    While a < b do QueryPerformanceCounter(a);
end;

Aufruf: DelayQPC(1000); // 1 msec
        DelayQPC(10000); // 10 msec

himitsu 3. Mär 2009 08:54

Re: Problem mit sleep
 
Mit einem Sleep, Delay oder gar DelayQPC bekommt man keine einheitlichen Intervalle hin.
selbst wenn sleep genauer wäre, würde dennoch das Intervall nicht stimmen.

Delphi-Quellcode:
mach was << das braucht auch Zeit
warte 10 ms

mach was << dieses ebenfalls
warte 10 ms

mach was << und hier wieder
warte 10 ms
macht also zusammen mehr als 30ms

man müßte also, wenn schon, die Zeit ab einem festen Punkt aufrechnen
Delphi-Quellcode:
Temp = Zeit;

mach was
Temp + 10 ms
warte bis Temp = Zeit

mach was
Temp + 10 ms
warte bis Temp = Zeit

mach was
Temp + 10 ms
warte bis Temp = Zeit
oder
Zitat:

Zitat von Cyf
Wäre es nicht einfacher die Kurve zu approximieren?

Delphi-Quellcode:
Start = Zeit;

mach was
warte x ms

Temp = Zeit - Start
Start = Zeit;
mach was, das Temp ms später zum vorherigen Ereignis entspricht
warte x ms

Temp = Zeit - Start
Start = Zeit;
mach was, das Temp ms später zum vorherigen Ereignis entspricht
warte x ms
beziehungsweise
Delphi-Quellcode:
Start := Zeit;

mach was
warte x ms

mach was, das (Zeit - Start) ms entspricht
warte x ms

mach was, das (Zeit - Start) ms entspricht
warte x ms

I love Delphi 3. Mär 2009 09:32

Re: Problem mit sleep
 
Hallo,
habe jetzt noch ein bisschen weiterentwickelt. Die Pause soll ja nach Ausgabe eines Wertes erfolgen, danach zeichnet das Programm aber noch einen Graphen. Ich nehme nun einmal die Zeit mit QueryPerfomanceCounter vorm Zeichnen und einmal danach. Die Differenz ziehe ich dann bei der Pause ab, welche ich mit einer Funktion ähnlich der Funktion von hathor realisiere.

Ergebnis:
Ich habe nun auf einem dritten Rechner (müsste eigentlich schlechter sein als die beiden anderen) eine Differenz von nur noch 37 ms festgestellt. Das Problem ist also gelöst!

Vielen Dank!
I love Delphi!

Edit: Danke auch himitsu! Du hattest ja eigentlich die gleiche Idee wie ich :)

QuickAndDirty 3. Mär 2009 09:44

Re: Problem mit sleep
 
Das was er braucht sollte über die Soundkarte möglich sein.
Einfach eine Wavedatei unendlich oft wiedergeben.

Du must NUR einen Wandler haben der das auf RS232 umwandelt...eine Art MODEM vielleicht.

I love Delphi 3. Mär 2009 12:41

Re: Problem mit sleep
 
Danke nochmal für alle Lösungen,
wenn ich Zeit habe, probiere ich das mit der Soundkarte vielleicht wirklich nochmal aus! :)

I love Delphi!

hathor 3. Mär 2009 14:48

Re: Problem mit sleep
 
Liste der Anhänge anzeigen (Anzahl: 2)
Die Auflösung des "normalen" Timers kann man sich auch anzeigen lassen:
.
Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

type msecs = real;

implementation

{$R *.dfm}

function resolution: msecs;
var t0 : tdatetime;
begin
    t0 := now;
    while now = t0 do ;
    result := msecsperday * (now -t0);
end;

function Strip(L,C:char;Str:string):string;
{L is left,center,right,all,ends}
var I : byte;
begin
   Case Upcase(L) of
   'L' : begin      {Left}
            while (Str[1] = C) and (length(Str) > 0) do
               Delete(Str,1,1);
         end;
   'R' : begin      {Right}
            while (Str[length(Str)] = C) and (length(Str) > 0) do
               Delete(Str,length(Str),1);
         end;
   'B' : begin      {Both left and right}
            while (Str[1] = C) and (length(Str) > 0) do
               Delete(Str,1,1);
            while (Str[length(Str)] = C) and (length(Str) > 0) do
               Delete(Str,length(Str),1);
         end;
   'A' : begin      {All}
            I := 1;
            repeat
               if (Str[I] = C) and (length(Str) > 0) then
                  Delete(Str,I,1)
               else
                  I := succ(I);
            until (I > length(Str)) or (Str = '');
         end;
   end;
   Strip := Str;
end; {Strip}

function RealToStr(Number:extended;Decimals:byte):string;
var Temp : string;
const Floating = 255;
begin
   Str(Number:20:Decimals,Temp);
   repeat
        if copy(Temp,1,1) = ' ' then delete(Temp,1,1);
   until copy(temp,1,1) <> ' ';
   if Decimals = Floating then
   begin
      Temp := Strip('R','0',Temp);
      if Temp[Length(temp)] = '.' then
         Delete(temp,Length(temp),1);
   end;
   RealToStr := Temp;
end; {RealToStr}

function avgres : real;
var j : integer;
begin
    result := 0;
    for j := 1 to 100 do
       result := result + resolution;
    result := result /100;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Label1.Caption:=' Average resolution = '+ RealToStr(avgres,3)+' msecs';
end;

end.
Bei mir (WIN XP,Notebook) werden 15.620 msec angezeigt:
das heisst also: ein Sleep(16) ist der niedrigste, sinnvolle Wert.

Bei hoher Belastung der CPU steigt der Wert deutlich an - siehe Anhang:

Sleep(0) dauert 0,010msec, aber:
Bei hoher Belastung der CPU steigt der Wert von Sleep(0) deutlich an - bis fast 50 msec- siehe Anhang:

hathor 4. Mär 2009 07:41

Re: Problem mit sleep
 
Nur zur Information - siehe oben:

Sleep(0) dauert 0,010msec, aber:
Bei hoher Belastung der CPU steigt der Wert von Sleep(0) deutlich an - bis fast 50 msec- siehe Anhang oben.

Nachtrag:
Wahrscheinlich ist mir bei der Berechnung des Sleep(0)-Wertes ein Denkfehler unterlaufen, denn ich habe den Wert von "Resolution" abgezogen:

Gemessen:
Resolution: 15,620 msec
Sleep(0): 15,630 msec

Wert(Sleep(0)) - Wert(Resolution) = Sleep0 (=vermutlich falsch!!!)

Was ist Euere Meinung?

himitsu 4. Mär 2009 09:16

Re: Problem mit sleep
 
du mußt bedenken, daß die Dauer bedingt durch die Messung nie immer genau gleich sein kann.

z.B. wenn GetTickCount eine Taktrate von 8ms hat, dann wäre die Dauer von Sleep(0) bis Sleep(7) Gundsätzlich erstmal gleich, aber dazu kommt noch der Zeitpunkt wo man das Sleep bzw die Messung startet.

Delphi-Quellcode:
Zeit  Wert von     Start       Start
in ms GetTickCount Sleep(1..8) Sleep(9..16)
                     + Dauer     + Dauer

0      0             #            #
1      0             .           .
2      0             .           .
3      0             .  #        .
4      0             .  .       .
5      0             .  .       .
6      0             .  .       .   #
7      0             .  .  #    .   .
8      1 . . . . . . 8ms 6ms 1ms .   .
9      1                          .   .
10     1                          .   .
11     1                          .   .
12     1                          .   .
13     1                          .   .
14     1                          .   .
15     1                          .   .
16     2  . . . . . . . . . . . . 16ms 10ms
17     2
18     2


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:10 Uhr.
Seite 3 von 4     123 4      

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