![]() |
GetTickCount beeinflusst von PC Auslastung
Hallo!
Ich habe heute im Prinzip eine Stoppuhr fertiggestellt, die ich für genaue zeitmessungen bräuchte. Um genau zu sein würde ich sie benutzen um "Splits" beim Speedrunnen eines Spiels zu setzen. (wenn ihr nicht wisst, was es ist ist es auch nicht schlimm :wink: ) Auf jeden Fall soll die Zeitmessung sehr genau ablaufen, allerdings habe ich gemerkt das bei hoher CPU auslastung (die beim Streamen des Spiels der Fall ist) die Uhr manchmal flakert und auch langsamer läuft als ein profesionell gestalteter timer. Mein code ist folgender:
Code:
Ja, ich weiß für die umbennenung war ich noch zu faul, die mach ich oft erst wenns es funktioniert ^^
procedure TForm1.Timer1Timer(Sender: TObject);
begin Time:=Time+GetLocalTime-Tick; Segment:=Segment+GetLocalTime-Tick; Label1.Caption:=MSFormat(Time); Tick:=GetLocalTime; end; "MSFormat" Formatiert nur die Zeit, in MS in das Format Min:Sek:Millisek, also sollte das eigentlich auch kein Problem darstellen. Naja, ich habe es auch so verstanden dass der benannte "Tick" in Ms gemessene Zeit seit dem Start des Computers ist. Und meine Theorie: dass wenn der CPU überfordert wird irgendwas langsamer läuft. Nach einem frischen Neustart ohne andere geöffnete Programme funktioniert soweit alles prima. Sobald ich aber aufnahme/ das Streamen Starte habe ich z.T. bei 1 Minute bereits 2 Sekunden abweichung zu dem anderen Programm. Irgendwelche Ideen? :pale: Vielen Dank im Vorraus! |
AW: GetTickCount beeinflusst von PC Auslastung
"sehr genau" und GetTickCount/TTimer/... wiedersprechen sich.
Alles unterhalb weniger Vielfacher von 16 ms kannst du vergessen. Und ausßerdem bist du selber für die Ungenauigkeit verantwortlich.
Delphi-Quellcode:
Und wenn Time und/oder Tick auch nicht Fließkommazahlen sind, dann kommen schnell auch noch die Rundungsfehler dieser Typen dazu.
procedure TForm1.Timer1Timer(Sender: TObject);
var Temp: TDateTime; begin Temp := GetLocalTime; Time := Time + Temp - Tick; Segment := Segment + Temp - Tick; Label1.Caption := MSFormat(Time); Tick := Temp; end; ![]() Multimedia-Timer QueryPerformanceCounter ASM RDTSC (Read Time Stamp Counter) uvm. |
AW: GetTickCount beeinflusst von PC Auslastung
Wenn Du die CPU-Last wissen willst, dann zeige sie an:
Timer1.Interval:= 1000; // kürzer muss es nicht sein!
Delphi-Quellcode:
private
Times: TThread.TSystemTimes; procedure TForm1.FormCreate(Sender: TObject); begin TThread.GetSystemTimes(Times); end; procedure TForm1.Timer1Timer(Sender: TObject); var Usage: Integer; begin Usage := TThread.GetCPUUsage(Times); ProgressBar.Position := Usage; // Percent 0 - 100 end; |
AW: GetTickCount beeinflusst von PC Auslastung
Also die Zeit zu messen in dem man im Timer OnTimer Ereignis die Zeit, bzw. Ticks addiert ist leider ein unsinniges Unterfangen. Das Intervall ist nicht gleichmäßig. Stellt man das Intervall auf 100 ms, kann, wird aber eher nicht, das Ereignis 10 mal in der Sekunde aufgerufen werden. Somit bringt das nichts.
Besser ist den Zeitunterschied zu messen, z. B. so:
Delphi-Quellcode:
Beim Start wird die aktuelle Uhrzeit gemessen. Danach wird immer die Differenz zu der Startzeit gemessen. Da die Uhrzeit separat getaktet wird, sollte PC Auslastung keine Rolle spielen.
uses
DateUtils; var T1, T2: TTime; procedure TForm1.FormCreate(Sender: TObject); begin Timer1.Interval := 1; Timer1.Enabled := False; end; procedure TForm1.Button1Click(Sender: TObject); begin T1 := 0; T2 := 0; Timer1.Enabled := True; end; procedure TForm1.Timer1Timer(Sender: TObject); var MSBetween: Int64; TimeTemp: TTime; begin if T1 = 0 then T1 := Time; T2 := Time; MSBetween := MilliSecondsBetween(T1, T2); TimeTemp := MSBetween / 24 / 60 / 60 / 1000; Label1.Caption := FormatDateTime('hh:nn:ss:zzz', TimeTemp); end; //EDIT: Ich hab mir das Ganze mal angeguckt und da sind einige unnötige Zeilen. Der Code oben nur etwas kürzer:
Delphi-Quellcode:
uses
DateUtils; var T1: TTime; procedure TForm1.FormCreate(Sender: TObject); begin Timer1.Interval := 1; Timer1.Enabled := False; end; procedure TForm1.Button1Click(Sender: TObject); begin T1 := 0; Timer1.Enabled := True; end; procedure TForm1.Timer1Timer(Sender: TObject); var TimeTemp: TTime; begin if T1 = 0 then T1 := Time; TimeTemp := MilliSecondsBetween(T1, Time) / 24 / 60 / 60 / 1000; Label1.Caption := FormatDateTime('hh:nn:ss:zzz', TimeTemp); end; |
AW: GetTickCount beeinflusst von PC Auslastung
Vielen Dank für die schnellen Antworten!
(Und nochmal zur Anmerkung: meine Kenntnisse gehen kaum über ausgeweitete Grundkenntnisse hinaus, und ich bringe mir alles nach und nach anhand von Beispielen bei) Zitat:
Also die Idee mit GetLocalTime hatte ich erst auch, aber da ich irgendwie nicht herausgefunden habe wie ich das zu benutzen habe, hatte ich es dann doch gelassen. Und jetzt als ich versucht habe das so zu benutzen, gibt mir Delphi immer den fehler "nicht genügent wirkliche Parameter" und was ich dann in die Klammer setzen soll finde ich irgendwie auch nicht heraus. Was ich gefunden habe war [...] GetlocalTime(_Systemtime(now)); Ich bin mit mehr oder weniger ausprobieren an diesen Punkt gekommen. Aber egal ob ich nun now oder eine Zahl eingebe sagt mir Delphi: "ungültige Typunwandlung" :/ Und den Vorschlag von Popov versuche ich jetzt mal zu implementieren und zu verstehen. :oops: Wenn das -warumauchimmer- auch nicht klappen sollte versuche ich wohl mal alles über die TStopwatch zu machen |
AW: GetTickCount beeinflusst von PC Auslastung
Es sollte klappen.
|
AW: GetTickCount beeinflusst von PC Auslastung
Auch wenn ich gerne sagen würde dass es geht, muss ich leider enttäuscht sagen, dass ich diese Version eines Timers zwar komplett verstehe, und auch keine Fehler bekomme , allerdings bleibt er immer auf 00:00:000 stehen.
Ich hasse es wenn es von der Logik gehen müsste, aber es einfach nicht geht :evil: Ich gehe persönlich davon aus, dass bei mir "time" vielleicht nicht richtig abgegriffen wird? |
AW: GetTickCount beeinflusst von PC Auslastung
Der Timer1 ist nicht dazu da um etwas zu zählen, schon gar nicht Ticks, sondern nur um den aktuellen Stand in Label1.Caption anzuzeigen:
Delphi-Quellcode:
uses
DateUtils; //Die Unit DateUtils wird für die Funktion MilliSecondsBetween benötigt var T1: TTime; //Globale TTime Variable um die Startzeit zu merken procedure TForm1.FormCreate(Sender: TObject); begin // Interval ist für die Zählung irrelevant. // Sagt nur aus wie oft die Anzeige aktualisiert wird. Timer1.Interval := 1; Timer1.Enabled := False; //Timer1 zuerst deaktivieren end; procedure TForm1.Button1Click(Sender: TObject); begin // Es wird nicht ab 0 gezählt. // Die 0 ist nur dazu da um festzustellen ob T1 bereits einen Wert hat T1 := 0; Timer1.Enabled := True; // Stoppur starten end; procedure TForm1.Timer1Timer(Sender: TObject); var TimeTemp: TTime; begin if T1 = 0 then // Wenn T1 = 0, dann ist es der ersten Durchlauf T1 := Time; // In dem Fall die Startzeit merken // Nun die Differenz (Int64) zwischen Startzeit und aktuellen Zeit vergleichen. // Bei TDateTime sind ganze Werte Daten, Nachkommawerte Zeiten. // Deshalb TimeTemp durch 24 Stunden, 60 Minuten, 60 Sekunden und 1000 Millisekunden teilen // Ergebnis ist eigentlich Zeit ab 00:00:00 Uhr TimeTemp := MilliSecondsBetween(T1, Time) / 24 / 60 / 60 / 1000; // Was angezeigt wird ist eigentlich die Uhrzeit, man merkt aber keinen Unterschied Label1.Caption := FormatDateTime('hh:nn:ss:zzz', TimeTemp); end; |
AW: GetTickCount beeinflusst von PC Auslastung
Okay auf die Idee hätte ich mal vorher kommen können: in einem neu geöffnetem Projekt funktioniert der Code. Allerdings in dem ganzen Konstrukt nicht <.<
Danke die kommentierte Version hat mir das ganze nocheinmal klar gemacht. Ich versuche jetzt mal die Stelle zu finden an der es hakt indem ich systematisch auskommentiere. |
AW: GetTickCount beeinflusst von PC Auslastung
Ok Ich habe meinen Fehler gefunden...
Ich hatte eine Variable vorher "Time" genannt, die immer durch den Zähler verändert wurde - logischerweise blieb es die ganze Zeit über auf Null. Jetzt, da ich die Variable umbenannt habe, läuft der Timer ganz normal hoch. Ich habe mein ganzes Programm inzwischen auch schon umgeschrieben, dass es mit den Werten auch rechnet und alles funktioniert Vielen, vielen Dank für die Hilfe!! Das ist echt riesig! :thumb: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:19 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-2025 by Thomas Breitkreuz