Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Merkwürdigkeit mit Sleep() (https://www.delphipraxis.net/153599-merkwuerdigkeit-mit-sleep.html)

Uwe Raabe 10. Aug 2010 09:03

AW: Merkwürdigkeit mit Sleep()
 
Zitat:

Zitat von jfheins (Beitrag 1040678)
[OT]
Vielleicht wird ja mal die Dezimalsekunde eingeführt, sodass ein Tag 10 Stunden hat, mit je 100 Minuten und jede Minute 100 Sekunden :stupid:
[/OT]

Gibt's schon: Industrieminute

Ich hatte mal mit sowas zu tun. Du glaubst gar nicht, wie lange man in so einem Fall mit Leuten über Zeiten diskutieren kann ohne hinterher zu einem Konsens zu kommen.

Luckie 10. Aug 2010 09:09

AW: Merkwürdigkeit mit Sleep()
 
Zitat:

Zitat von Shark99 (Beitrag 1040640)
Ich will ein mal Pro Sekunde den CPU Verbrauch anzeigen. Da Windows kein Echtzeit Betriebssystem ist, habe ich mit einer Abweichung gerechnet, allerdings mit 10ms, nicht 160.

Weißt du wie lange 160 Millisekunen sind? Ein menschlicher Wimpernschlag dauert ca. 100 Millisekunden (laut Wikipedia). Und jetzt überleg noch mal, ob du die CPU-Auslastung wirklich so genau anzeigen können musst.

Eine Zeitscheibe unter Windows NT hat eine länge von 22 Millisekunden. das heißt ein Thread bekommt für 22 Sekunden Rechenzeit zugeteilt. Dann wird zum nächsten Thread, abhängig von der Priorität gewechselt. Gibts du bei Sleep einen Wert unter 22 Millisekunden an, gibt der Thread den Rest seiner Zeitscheibe sofort ab und kehrt in den zuteilungsfähigen Zustand zurück und kann, wenn er wieder dran ist Rechnzeit zugeteilt bekommen.

jfheins 10. Aug 2010 09:32

AW: Merkwürdigkeit mit Sleep()
 
Zitat:

Zitat von Luckie (Beitrag 1040692)
Zitat:

Zitat von Shark99 (Beitrag 1040640)
Ich will ein mal Pro Sekunde den CPU Verbrauch anzeigen. Da Windows kein Echtzeit Betriebssystem ist, habe ich mit einer Abweichung gerechnet, allerdings mit 10ms, nicht 160.

Weißt du wie lange 160 Millisekunen sind? Ein menschlicher Wimpernschlag dauert ca. 100 Millisekunden (laut Wikipedia). Und jetzt überleg noch mal, ob du die CPU-Auslastung wirklich so genau anzeigen können musst.
Eine Zeitscheibe unter Windows NT hat eine länge von 22 Millisekunden.

Wie sinnvoll das ist, ist irrelevant. Wenn das System mit einer Genauigkeit von 20ms arbeitet, dann möchte man diese Genauigkeit auch gerne bekommen. Das ist ja nichts anderes als wenn eine Waage mit "Fehler: +- 20g" beworben wird,du tust ein 1kg Stück drauf und bekommst 1,16kg angezeigt. Da würdest du dich auch wundern ;)
Aber wie gesagt, die Abweichung liegt nicht an Windows sondern am Fehler in der Rechnung - OSI Layer 8 Problem ;)

Luckie 10. Aug 2010 11:26

AW: Merkwürdigkeit mit Sleep()
 
Nein, die Zeitscheibe ist nur 22 Millisekunden lang. Wann dein Thread wieder Rechenzeit bekommt, hängt vom Scheduler ab, wie viele andere Threads laufen und mit welcher Priorität. Hast du im System einen Thread mit der höchsten Priorität (Zeitkritisch), kannst du dich mit deinem Programm dumm und dämlich warten.

himitsu 10. Aug 2010 11:40

AW: Merkwürdigkeit mit Sleep()
 
was man machen kann, das ist, solange die Operation kürzer ist, als die "Zeitscheibe", bzw. zusammenhängende Rechenzeit, welche einem Windows im Moment gewährt:

Delphi-Quellcode:
Sleep(0);
MachWas;
Wenn MachWas nun also weniger Zeit benötigt, als die oftmals vorliegenden 22 ms, dann wird es mit sehr hoher Wahrscheinlichkeit zusammenhängend ausgeführt.

Sleep 0 gibt die Rechenzeit an Andere Programme ab und fast sofort, wenn das eigene Programm wieder dran, beginnt die Abarbeitung von MachWas, welches somit fast die volle Zeit zur Verfügung hat.

Ohne das Sleep könnte es ja sein, daß das Programm schon fast seine komplette Zeiteinheit aufgebracht hat, MachWas kurz vorm Ende gestartet wird und somit mitten in MachWas Windows die Kontrolle an einen anderen Thread/Programm abgibt.

p80286 10. Aug 2010 13:57

AW: Merkwürdigkeit mit Sleep()
 
War Da nicht vor einiger Zeit ein thread in dem Tickcount für solche Messungen als untauglich bewertet wurde?

Da ich's nicht brauche habe ich die Alternative vergessen.
Aber wie schon oben erwähnt MUSS es so genau sein?

Gruß
K-H

himitsu 10. Aug 2010 14:39

AW: Merkwürdigkeit mit Sleep()
 
GetTickCount arbeitet aktuell mit einem ~16 ms-Intervall.
> z.B. QueryPerformanceCounter

hathor 10. Aug 2010 19:01

AW: Merkwürdigkeit mit Sleep()
 
AVERAGE RESOLUTION - bei WIN XP ca. 15.620 msec, bei meinem WIN 7 64Bit: 1 msec!
Kann jemand was dazu schreiben?
Was kann man damit anfangen? Der Wert ist sehr CPU-Last-abhängig.

Delphi-Quellcode:
unit Unit1;

interface

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

CONST
  Floating = 255;

type msecs = real;

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

var
  Form1: TForm1;

implementation

{$R *.dfm}

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;
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 resolution: msecs;
var t0 : tdatetime;
begin
    t0 := now;
    while now = t0 do ;
    result := msecsperday * (now -t0);
end;


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

procedure TForm1.Timer1Timer(Sender: TObject);
begin
 Label1.Caption:=' Average resolution = '+ RealToStr(avgres,3)+' msec'; //15.620 msec
end;

end.

xZise 10. Aug 2010 19:11

AW: Merkwürdigkeit mit Sleep()
 
Zitat:

Zitat von p80286 (Beitrag 1040813)
War Da nicht vor einiger Zeit ein thread in dem Tickcount für solche Messungen als untauglich bewertet wurde?[...]

Es ist nicht super genau, aber es gibt ein relativ gutes Ergebnis für den Aufwand. Wenn man mal eben was testen will, ist der PerformanceCounter schon wesentlich komplexer. Abgesehen davon wurde der ja auch schon genannt.

Und zu den ungenauen Zahlen: Ist es nicht so, dass ein Extended nicht alle Zahlen darstellen kann? Es also zwingenderweise "Sprünge" geben muss? Es kann natürlich sein, dass diese Sprünge < 1 ms sind, aber trotzdem finde ich, den Umgang mit Ganzzahlen angenehmer :P

MfG
Fabian

PS: Gibts nicht sowas wie "SecondsBetween". Das durch Tausend und man dürfte das richtige Ergebnis bekommen, oder (egal ob Industrieminute oder nicht :D )?

Medium 10. Aug 2010 21:17

AW: Merkwürdigkeit mit Sleep()
 
Die Genauigkeit der Zeitdarstellungen ist bei weitem gut genug. Das "Problem" ist einfach, dass der Windows Scheduler CPU Zeit an die Prozesse verteilt, und jedem Prozess ein Minimum an Zeit gewährt, die sog. kleinst mögliche Zeitscheibe. Die ist unter verscheidenen OSs unterschiedlich, aber die Essenz ist die selbe: Es ist NIEMALS gesichert, dass dein Prozess nach exakt N Millisekunden wieder an die Reihe kommt. Derartige Zusagen treffen, wie gesagt, nur Echtzeit-Betriebssysteme.

Man kann sich drehen und wenden wie man will, man wird in der "Consumer"-Windowswelt immer damit rechnen müssen, keine millisekundengenauen Scheibchen zu bekommen. Das kann per Zufall mal sein, aber damit rechnen darf ich einfach nicht. Egal mit welcher Methode. End of story.


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:27 Uhr.
Seite 2 von 3     12 3      

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