Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Zeitbestimmung nur genau auf 10 Millisekunden (https://www.delphipraxis.net/21044-zeitbestimmung-nur-genau-auf-10-millisekunden.html)

AndreasZZZ 27. Apr 2004 09:22


Zeitbestimmung nur genau auf 10 Millisekunden
 
Hallo,

ich weiss, dass zum Thema Genauigkeit von Zeitfunktionen schon viel geschrieben wurde, aber zu meinem Problem konnte ich noch nichts passendes finden. Auch Torry's Delphi-Page oder Suche hier im Forum oder in den Newsgroups war wenig erfolgreich.

Ich habe sehr viel gefunden zum Thema Zeitmessung über GetTickCount oder QueryPerformanceFrequency/QueryPerformanceCounter aber mir geht es um die absolute Zeitbestimmung.

Ich habe ein Programm, das über IdTCPServer Telegramme von etwa Kommunikationspartners empfängt. Alle Telegramme werden mitprotokolliert. Das Logfile sieht wie folgt aus:
2004.04.27 10:07:01.125 - RCV: <Telegramminhalt Anfragetelegramm>
2004.04.27 10:07:01.145 - SND: <Telegramminhalt Antwortelegramm>

Mit fiel nun auf, dass nahezu alle Logfileeinträge mit 5 endeten, d.h. 10:07:01.125, 10:07:01.145, 10:07:01.155, 10:07:01.165 etc.
D.h. zwischen den Telegrammen lager IMMER entweder 10 oder 0 Millisekunden. Das kam mir merkwürdig vor.
Die Zeit ermittle ich durch NOW und schreibe sie mit FormatDateTime als String in das Logfile.

Zuerst dachte ich, dass das Schreiben ins Logfile 10 Millisekunden dauern würde, also habe ich nur Bildschirmausgaben gemacht, aber das Ergebnis blieb gleich.

Dann habe ich ein kleines Testprogramm geschrieben:

Delphi-Quellcode:
program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

const MAXANZ=10;
var i    : Integer;
var dtTest: Array[1..MAXANZ] of TDateTime;
begin
  WriteLn('Test mit NOW');
  for i:=1 to MAXANZ do
  begin
    dtTest[i]:=Now;
    Sleep(3);
  end;
  for i:=1 to MAXANZ do
  begin
    Write(dtTest[i]:0:15);
    WriteLn(' -  '+FormatDateTime('HH:NN:SS.ZZZ',dtTest[i]));
  end;

  WriteLn('Test mit TIME');
  for i:=1 to MAXANZ do
  begin
    dtTest[i]:=Time;
    Sleep(3);
  end;
  for i:=1 to MAXANZ do
  begin
    Write(dtTest[i]:0:15);
    WriteLn(' -  '+FormatDateTime('HH:NN:SS.ZZZ',dtTest[i]));
  end;
  ReadLn;
end.
Ich schreibe zuerst nur in ein Array und mache anschliessend die Bildschirmausgabe. Mit dem Sleep(3) sollte sich die Bildschirmausgabe um je 3 Millisekunden unterscheiden. Tut sie aber nicht:

Code:
Test mit NOW
38104.425165578701100  -  10:12:14.306
38104.425165694447100  -  10:12:14.316
38104.425165810185700  -  10:12:14.326
38104.425165925924400  -  10:12:14.336
38104.425166041663000  -  10:12:14.346
38104.425166157409000  -  10:12:14.356
38104.425166157409000  -  10:12:14.356
38104.425166273147600  -  10:12:14.366
38104.425166388886300  -  10:12:14.376
38104.425166504632200  -  10:12:14.386

Test mit TIME
0.425184710648148  -  10:12:15.959
0.425184826388889  -  10:12:15.969
0.425184942129630  -  10:12:15.979
0.425185057870370  -  10:12:15.989
0.425185173611111  -  10:12:15.999
0.425185289351852  -  10:12:16.009
0.425185405092593  -  10:12:16.019
0.425185520833333  -  10:12:16.029
0.425185636574074  -  10:12:16.039
0.425185752314815  -  10:12:16.049
Es liegen immer genau 10 oder 0 Millisekunden (10:12:14.356) dazwischen. Wenn ich mir dann den TDateTime ansehe, dann stimmt der Werden bis auf 15 Stellen nach dem Komma exakt überein.

In den Hilfe steht, das NOW nicht für Millisekunden geeignet ist, daher habe ich auch TIME genommen, aber das Ergebnis bleibt gleich.

Dauert ein Aufruf von NOW oder TIME wirklich 10 Millisekunden? Kann ich mir nicht vorstellen. Und was ist mit den exakt übereinstimmenden Werten?
Gibt es eine genauere und/oder schnellere Version von NOW oder TIME?

Ich verwende Delphi 7 Professional.

Bye
Andreas

sakura 27. Apr 2004 09:24

Re: Zeitbestimmung nur genau auf 10 Millisekunden
 
Ja, Now() ist nur auf 10 ms genau, aber mit [dp="QueryPerformance*"]QueryPerformanceCounter() und QueryPerformanceFrequency()[/dp] kannst Du viel genauere Ergebnisse erzielen.

...:cat:...

AndreasZZZ 27. Apr 2004 09:35

Re: Zeitbestimmung nur genau auf 10 Millisekunden
 
Zitat:

Zitat von sakura
mit [dp="QueryPerformance*"]QueryPerformanceCounter() und QueryPerformanceFrequency()[/dp] kannst Du viel genauere Ergebnisse erzielen.

Ich will aber nicht die Zeit zwischen zwei Telegrammen messen, sondern nur die aktuelle Uhrzeit genau ausgeben.
Ich wüsste jetzt nicht, wie man das mit QueryPerformanceCounter machen kann. Ausserdem ist die Funktion ja angeblich auf einem Pentium 4 mit HT ungenau.

Noch eine Idee? Oder gibt es irgendeine andere Freeware oder Shareware-Version von NOW, die genauer arbeitet?

Und wenn NOW nur auf 10 Millisekunden genau ist, ich in meiner Schleife einen Sleep(3) habe, dann müssten doch immer 3 Zeilen gleich sein und nicht immer genau 10 Millisekunden dazwischen liegen.

Bye
Andreas

maximov 27. Apr 2004 09:58

Re: Zeitbestimmung nur genau auf 10 Millisekunden
 
Zitat:

Zitat von AndreasZZZ
Zitat:

Zitat von sakura
mit [dp="QueryPerformance*"]QueryPerformanceCounter() und QueryPerformanceFrequency()[/dp] kannst Du viel genauere Ergebnisse erzielen.

Ich will aber nicht die Zeit zwischen zwei Telegrammen messen, sondern nur die aktuelle Uhrzeit genau ausgeben.
Ich wüsste jetzt nicht, wie man das mit QueryPerformanceCounter machen kann. Ausserdem ist die Funktion ja angeblich auf einem Pentium 4 mit HT ungenau.

Und auf einigen AMD prozessoren sogar grob falsch!
Zitat:


Noch eine Idee? Oder gibt es irgendeine andere Freeware oder Shareware-Version von NOW, die genauer arbeitet?

Also das is jetzt nicht direkt eine neue now funktion, aber ein high-res-counter, der dieses AMD problem umgeht -> RDTSC Library

http://www.specosoft.com/en/download.html

Der kann angeblich nanosekunden auflösung machen. Mit nen bisschen addition und subtraction kann man daraus wohl eine eigene HighResNow funktion basteln :wink:

sakura 27. Apr 2004 10:17

Re: Zeitbestimmung nur genau auf 10 Millisekunden
 
Zitat:

Zitat von AndreasZZZ
Und wenn NOW nur auf 10 Millisekunden genau ist, ich in meiner Schleife einen Sleep(3) habe, dann müssten doch immer 3 Zeilen gleich sein und nicht immer genau 10 Millisekunden dazwischen liegen.

Wer sagt denn, daß Sleep unter 10ms genau ist ;) Sleep basiert intern auch auf Now :roll:

...:cat:...

fiasko 27. Apr 2004 10:27

Re: Zeitbestimmung nur genau auf 10 Millisekunden
 
Ich wollte nur anmerken das du unmöglich die Uhrzeit genau auslesen kannst. Die Uhr im Rechner ist getaktet... die reale Zeit ist aber wenn mich nicht alles täuscht kontinuierlich :-).
Vielleicht bekommst du ja bessere Ergebnisse wenn du den RDTC oder wie das Ding auch immer heist ausliest (hab noch irgendwo ne Unit dafür). Der wird mit jedem Prozessortick inkrementiert... das macht natürlich nur Sinn zum Messen von Zeitabständen.

Jörn 27. Apr 2004 10:32

Re: Zeitbestimmung nur genau auf 10 Millisekunden
 
Man könnte ja einmal die Systemzeit messen, und dann immer weiter hochzählen mit QueryPerformanceCounter. Ach ja, das ist nicht ungenau bei AMD oder P4 das ist Stuß! Weil der hat nichts, aber auch rein gar nix mit dem Prozessor zu tun. Das läuft nämlich vom BIOS aus. Und wenn es ungenau ist, dann liegt es am BIOS. Außerdem können die Werte gar nicht so falsch sein, weil dann Netzwerkspiele, die fast alle darauf basieren (von rundenbasierten Games usw mal ausgenommen) nicht synchron wären. Sind sie aber (im Normalfall).

sakura 27. Apr 2004 10:34

Re: Zeitbestimmung nur genau auf 10 Millisekunden
 
Zitat:

Zitat von Jörn
Ach ja, das ist nicht ungenau bei AMD oder P4 das ist Stuß!

Bist Du Dir sicher - irgendwer hat hier mal den Beweis angetreten und :!: Microsoft bestätigt das unabhängig davon auch.

...:cat:...

maximov 27. Apr 2004 12:00

Re: Zeitbestimmung nur genau auf 10 Millisekunden
 
Zitat:

Zitat von Jörn
... Außerdem können die Werte gar nicht so falsch sein, weil dann Netzwerkspiele, die fast alle darauf basieren (von rundenbasierten Games usw mal ausgenommen) nicht synchron wären. Sind sie aber (im Normalfall).

Das ist es ja grade! Ich musste schmerzhaft feststellen das ein spiel von, das QueryPerformanceFrequency() benutzte, auf einem AMD prozessor (oder BIOS) mindestens 10 mal langsamer lief. Man muss sich schon selbst drumm kümmern, dass der frequenz-faktor korrekt ermittelt wird -> so wie es die unit macht, deren link ich oben gepostet habe!

Jörn 27. Apr 2004 16:59

Re: Zeitbestimmung nur genau auf 10 Millisekunden
 
Sorry, kann ich mir echt nicht vorstellen. Das würde in jeder miesen Gamestar oder so stehen auch wenn die keine Hardware-only Zeitschrift sind. Und was MS sagt oder nicht, da hör ich sowieso nicht drauf. Die sagen auch WinXP sei sicher. Und das wäre mir was Neues. Ganz davon abgesehen das Micrsosoft schon immer zu Intel stand. Falls jemand diesen Beweis findet, bin ich überzeugt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:03 Uhr.
Seite 1 von 2  1 2      

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