AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Große Abweichung zwischen Now und GetTickCount
Thema durchsuchen
Ansicht
Themen-Optionen

Große Abweichung zwischen Now und GetTickCount

Ein Thema von norwegen60 · begonnen am 2. Mai 2020 · letzter Beitrag vom 3. Mai 2020
Antwort Antwort
Seite 1 von 2  1 2      
Der schöne Günther

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

AW: Große Abweichung zwischen Now und GetTickCount

  Alt 3. Mai 2020, 05:57
Was genau ist deine Absicht?

Wenn du Zeiten miteinander vergleichen willst und dich dabei auch nicht von Dingen wie Sommer/Winterzeit
-Umstellungen aus dem Takt bringen lassen willst dann nimmt man keine lokale Uhrzeit sondern die Zeit in UTC. Für die Anzeige eines TDateTime für den Benutzer auf dem Bildschirm kann man dann UTC wieder in die lokale Zeitzone umrechnen.
  Mit Zitat antworten Zitat
Ghostwalker

Registriert seit: 16. Jun 2003
Ort: Schönwald
1.299 Beiträge
 
Delphi 10.3 Rio
 
#2

AW: Große Abweichung zwischen Now und GetTickCount

  Alt 3. Mai 2020, 06:21
Du arbeitest in deinem Beispiel mit, im übertragenen Sinn, Äpfel, Birnen und Pfirsichen

Now ist, wie Uwe schon angemerkt hat, die normal Systemzeit abhängig von der Zeitzone usw. Dabei wird, in Delphi, das ganze als TDateTime-Wert gespeichert. Dieser gibt im Vorkomma Teil die Anzahl der Tage seit dem 30.12.1899 (frag mich bitte nicht warum dieses Datum) an, im Nachkomma Teil, den Anteil der Zeit, die von den 24 Stunden vergangen sind an.

GetTickCount (besser GetTickCount64) gibt dir die Millisekunden seit Systemstart an. Damit ist das ganze soweit unabhängig von irgendwelchen Datums-/Uhrzeiten.

QueryPerformanceCounter ist ähnlich, aber wesentliche genauer. Abhängig ist das ganze aber von der Frequenz, in der gemessen werden kann (QueryPerformanceFrequency).

Was ich an deinem Beispiel kritisch sehen ist folgende Zeile:

Code:
dt2 := dtStart + (GetTickCount - iStart) / (1000 * 24 * 60 * 60);
Denn hier mischt du einen Wert, basieren auf der aktuellen Systemzeit (mit Zeitzone und Sommer-/Winterzeit), mit einem Wert basierend auf dem Systemstart. Noch dazu mit unterschiedlichen Datentypen (Integer und Double).

Je nachdem welche Zeitintervalle zu erwarten sind, würde ich auf TDateTime komplett verzichten und nur entweder mit GetTickCount64 oder QueryPerformanceCounter arbeiten. Wenn die Zeitintervalle größer sind, dann wie Günther schon anmerkte, mit TDateTime auf UTC.

Hoffe das hilft dir weiter.
Uwe
e=mc² or energy = milk * coffee²
  Mit Zitat antworten Zitat
norwegen60

Registriert seit: 23. Dez 2007
Ort: Schwarzwald
504 Beiträge
 
Delphi 12 Athens
 
#3

AW: Große Abweichung zwischen Now und GetTickCount

  Alt 3. Mai 2020, 08:19
Hallo zusammen,

ich glaube nicht dass ich Äpfel mit Birnen vergleiche. Ich vergleiche nur unterschiedliche Arten die eigentlich immer gleiche Zeit zu erfassen.

In dem Programm das ich betreue, werden zu bestimmten Zeitpunkten Messungen vorgenommen. Da muss in definierten Intervallen auch über längere Zeit (z.B. 30 Tage) innerhalb +/- 10 s gemessen werden (z.B. 30 Tage alle 60 Minuten oder aber auch 20 Minuten alle 2 Minuten)

Zu dem Messzeitpunkt wird auch die Datum/Uhrzeit dokumentiert. Wenn jetzt hin und wieder die Uhr nachgestellt wird, kann man das erklären. Wenn z.B. über den Sommer-/Winterzeit-Wechsel getestet wird, kann es sein, dass Prüfpunkt 11 um 2:45 gemessen wurde, Prüfpunkt 12 dann um 2:15. Um das zu erklären, soll das Programm künftig die Uhrzeit und eine "normierte Uhrzeit" vergleichen. Ist die Abweichung größer als 3s erfolgt ein Eintrag in ein Audittrail, dass die Uhr von außen verstellt wurde. Damit ist nachvollziehbar, warum sich die Benutzer-Uhr und unser Zeitgeber unterscheiden (Und damit auch die u.U. vom Benutzer über die eingetragenen Uhrzeiten nachgerechneten Intervalle).
Wenn aber solch seltsame Dinge auftreten wie in dem Chart kann man das kaum erklären. Bei einem Kurzzeittest, wo der Messintervall vielleicht nur 2 Minuten beträgt, glaubt niemand, dass die Uhrzeit halt mal 20s, mal 5s und dann wieder 20s korrigiert wurde.

Und egal, ob ich die Zeitdifferenz dann in Millisekunden (Integer) oder als Zeit (Double oder TDateTime) umrechne, sollten die in minimalen Grenzen gleich sein.

Im Anhang der Chart nachdem er die Nacht durchgelaufen ist (33600 s = 9:20 Stunden)
Wie man sieht sind die seltsamen Schwankungen zwei mal aufgetreten.
Die Messung der Dauer über QueryPerformanceCounter stimmt streckenweise ziemlich genau mit der überein, die ich über die Uhrzeiten gemessen habe.
GetTickCount weicht mittlerweile über 70s von der Zeit und QueryPerformanceCounter ab.

Ich glaube nicht, dass daran der folgende Code was ändert
Code:
dt2 := dtStart + (GetTickCount - iStart) / (1000 * 24 * 60 * 60);
Damit erschaffe ich mir nur eine isoliert Zeit. Ich werde es aber ausprobieren, ob sich was ändert wenn ich die Zeiten nur bei der Darstellung in eine einheitliches Format (dezimale Sekunden) ändere.

In der Nacht ist mir aber noch eine andere Vermutung gekommen. Das Programm incl. IDE läuft in einer VirtualBox. Vielleicht hat die negative Einflüsse.

Ich melde mich wenn ich dazu mehr weiß
Angehängte Grafiken
Dateityp: jpg TimeGetTickCount3.jpg (42,1 KB, 21x aufgerufen)
  Mit Zitat antworten Zitat
norwegen60

Registriert seit: 23. Dez 2007
Ort: Schwarzwald
504 Beiträge
 
Delphi 12 Athens
 
#4

AW: Große Abweichung zwischen Now und GetTickCount

  Alt 3. Mai 2020, 09:17
Ein kurzer Zwischenstand. Es sieht so aus, als wenn die Ursache in VirtualBox liegt. Im Anhang die Charts im direkten Vergleich.
  • Linkes Chart: Auf dem PC mit Win10: Nur wenige ms Abweichung und QueryPerfom genauer als GetTickCount
  • Rechtes Chart: In VirtualBox mit Win7: Zeiten schwanken zuerst und fangen dann an zu wandern
GetTickCount64 gibt es in XE noch nicht, sonst hätte ich es ausprobiert
Bleibt für mich noch die Frage, was stimmt denn jetzt auf VirtualBox am genausten?
Ich werde noch manuelle Test mit einer Stoppuhr und ClickButton machen

Der aktuelle Code:
Delphi-Quellcode:
procedure TForm7.btStartClick(Sender: TObject);
begin
  iStartTickCount := GetTickCount;
  iStartPerfCount := GetTickStart;
  dtStartTime := now;

  tiTest.Enabled := not tiTest.Enabled;

  lsDelta.Clear;
end;

procedure TForm7.tiTestTimer(Sender: TObject);
var
  dtDeltaTime: TDateTime;
  iDeltaTickCount: Int64;
  iDeltaPerfCount: Int64;

  rDeltaSecTime, rDeltaSecTickCount, rDeltaSecPerfCount: Double;

begin
  dtDeltaTime := now - dtStartTime;
  iDeltaTickCount := GetTickCount - iStartTickCount;
  iDeltaPerfCount := GetTickDelta(iStartPerfCount);

  rDeltaSecTime := dtDeltaTime * 24 * 60 * 60;
  rDeltaSecTickCount := iDeltaTickCount / 1000;
  rDeltaSecPerfCount := iDeltaPerfCount / 1000;

  lsDelta.Add(rDeltaSecTime - rDeltaSecTickCount);
  lsDeltaQ.Add(rDeltaSecTime - rDeltaSecPerfCount);
end;
Damit die Ergebnisse zwischen altem und neuen Code vergleichbar sind, habe ich als Basis die Uhrzeit gelassen
Angehängte Grafiken
Dateityp: jpg TimeGetTickCount4.jpg (41,7 KB, 27x aufgerufen)
  Mit Zitat antworten Zitat
Ghostwalker

Registriert seit: 16. Jun 2003
Ort: Schönwald
1.299 Beiträge
 
Delphi 10.3 Rio
 
#5

AW: Große Abweichung zwischen Now und GetTickCount

  Alt 3. Mai 2020, 09:38
Ok, das mit der Virtualisierung erklärt ein bischen was.

Wenn ich das mit der Virtualisierung (bin da soz. ein Noob) richtig verstanden hab, müssen die ganzen Aufrufe (QPC bzw. getTickCount) erstmal durch die Virtualisierungssoftware und dann ans Basis-BS geschleift werden. Das kostet natürlich Zeit, je nachdem was im Hintergrund vom Basis-BS noch läuft auch unterschiedlich lange.

Wenn ich mir die Charts aber so anschau, würd ich sagen ist QPC doch einiges genauer. Auch deine Aussage hinsichtlich, das die QPC - Werte sich auf einem Niveu einpendeln deutet darauf hin, das QPC hier die zuverlässigeren Werte liefert.
Uwe
e=mc² or energy = milk * coffee²
  Mit Zitat antworten Zitat
samso

Registriert seit: 29. Mär 2009
439 Beiträge
 
#6

AW: Große Abweichung zwischen Now und GetTickCount

  Alt 3. Mai 2020, 09:41
Wenn Du zwei verschieden Uhren (Performancecounter und Systemzeit) vergleichst, dann kann es je nach Qualität der Uhren schon zu erheblichen Abweichungen kommen. Solange Du keine der beiden Uhren mit einem exakten Zeitgeber (Atomuhr oder dergleichen) synchronisierst ist keine der beiden Uhren genau. Nach deinen Ausführungen scheint es bei Deiner Anwendung ja um eine Maschine zu handeln die abgeschottet von der Aussenwelt arbeitet und deren Uhr gelegentlich manuell nachgestellt wird.

So wie Du ausführst, willst Du lediglich einen Zeitsprung bei der Umstellung der Uhrzeit dokumentieren. Dann sollst Du doch sinnigerweise versuchen diesen Zeitsprung zu detektieren. Das finde ich vergleichsweise einfach. Du musst lediglich in halbwegs gleichmäßigen Zeitabständen (z.B. 200ms) prüfen, ob die Systemzeit um mehr als 3s von dem Zeitstempel vor 200ms abweicht. Ist das der Fall, dann hat jemand die Uhrzeit verstellt. Um die Sommerzeitumstellung korrekt zu berücksichtigen verwendest Du UTC (die bei der Sommerzeitumstellung gleichmäßig weiter läuft).

Delphi-Quellcode:
function NowUTC: TDateTime;
var
  SystemTime: TSystemTime;
begin
  GetSystemTime(SystemTime);
  Result := SystemTimeToDateTime(SystemTime);
end;
  Mit Zitat antworten Zitat
KarstenK

Registriert seit: 4. Dez 2007
Ort: Bärenthal
29 Beiträge
 
Delphi 2009 Enterprise
 
#7

AW: Große Abweichung zwischen Now und GetTickCount

  Alt 3. Mai 2020, 09:30
Hallo,

zu "The system can periodically refresh the time by synchronizing with a time source."

Die Zeitsynchronisierung per NTP ist in Windows etwas magic, es passiert nicht auf einmal, wenn die Zeitdifferenz klein ist, sondern past sich mit der Zeit an. (daher mein Interesse)

Schalte mal alle Netzwerkverbindungen aus um diesen Effekt auszuschliessen.

20 sec halte ich aber für nicht realistisch (scalierung in der Visualisierung?). Bei mir sind es -3 bis +3 ms (Ausreisser bis 9ms).

Kannst Du das Projekt mal hochladen?

Auf welcher hardware laufen deine Tests?
  Mit Zitat antworten Zitat
Hobbycoder

Registriert seit: 22. Feb 2017
939 Beiträge
 
#8

AW: Große Abweichung zwischen Now und GetTickCount

  Alt 3. Mai 2020, 09:46
Korrigiert mich wenn ich falsch liege, aber GetTickCount benötigt ja sinngemäß keinerlei Zeitanpassung, und kann somit ab Programmstart kontinuierlich mit rechnerspezifischem Takt fortlaufen. Now jedoch bedient sich der Systemzeit, die per NTP in bestimmten Intervallen angepasst wird, und demnach irgendwann von GetTickCount abweichen muss.

Wäre da nicht ein Vergleichstest auf möglichst vielen unterschiedlichen Rechner, und das raus ermittelte Mittelmaß der Abweichung notwendig um objektive darüber zu Diskutieren?
Gruß Hobbycoder
Alle sagten: "Das geht nicht.". Dann kam einer, der wusste das nicht, und hat's einfach gemacht.
  Mit Zitat antworten Zitat
norwegen60

Registriert seit: 23. Dez 2007
Ort: Schwarzwald
504 Beiträge
 
Delphi 12 Athens
 
#9

AW: Große Abweichung zwischen Now und GetTickCount

  Alt 3. Mai 2020, 11:05
Wäre da nicht ein Vergleichstest auf möglichst vielen unterschiedlichen Rechner, und das raus ermittelte Mittelmaß der Abweichung notwendig um objektive darüber zu Diskutieren?
Es geht mir nicht darum eine Zeit auf's hunderstel genau zu ermitteln. Nur die Schwankungen, die ich in meinen Charts aufgezeigt habe sind da und sie sind enorm. Die VirtauBox ist auf 2 Laptops gelaufen und die Ergebnisse sind ähnlich schlecht. Da brauche ich dann nicht möglichst viele anderen PC's um zu sehen, dass es andere PC's gibt, die besser oder noch schlechter sind.
Ich brauche eine Lösung, der ich auch auf der VirtualBox am meisten vertraue. Nach dem Vergleich mit der manuellen Stopuhr ist das ganz klar QueryPerformCounter.

Geändert von norwegen60 ( 3. Mai 2020 um 11:14 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: Große Abweichung zwischen Now und GetTickCount

  Alt 3. Mai 2020, 11:58
https://stackoverflow.com/questions/...est-at-runtime

Und was passiert danach?


Auch kann es beim Test nicht schaden mal im Host die Festplatte und CPU bissl auszulasten,
um die Auswirkungen des Host besser erkennen zu können.
Denn wenn du jetzt etwas als gut erachtest und auch dort "extreme" Abweichungen entstehen können, dann wäre dieses "gut" eventuell nicht "gut" genug.

Wobei die Abweichung dennoch hoch sein darf, so lange es konstant bleibt bzw. ansteigt, anstatt "zufällig" zu schwanken.
Auch ein Schwanken kann OK sein, denn wenn das System durch die Virtualisierung hängt/bremst, die Messung aber im Vergleich zu einem realen System sich vergleichbar verhält, dann stimmt dennoch das Ergebnis.

Beispiel: VM anhalten/pausieren und eine Stunde später wieder starten. (de extreme Variante eines kurzen Hängers)
Aus Sicht der VM und ihrer Programme ist dann nicht "wirklich" eine Stunde vergangen.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu ( 3. Mai 2020 um 12:09 Uhr)
  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 01:40 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