![]() |
TFileTime addieren
Wie addiere ich zwei TFileTime-Werte?
Delphi-Quellcode:
Das stimmt irgendwie nicht. Denn wenn ich das in eine Zeit umwandele,
CPUTime.dwLowDateTime := ProcList.Items[i].KernelTime.dwLowDateTime + ProcList.Items[i].UserTime.dwLowDateTime;
CPUTime.dwHighDateTime := ProcList.Items[i].KernelTime.dwHighDateTime + ProcList.Items[i].UserTime.dwHighDateTime;
Delphi-Quellcode:
kommt ein falscher Wert dabei raus.
FileTimeToLocalFileTime(CPUTime, lft);
FileTimeToSystemTime(lft, st); GetTimeFormatW(LOCALE_SYSTEM_DEFAULT, TIME_FORCE24HOURFORMAT, @st, nil, TimeStr, SizeOf(TimeStr)); |
Re: TFileTime addieren
Wozu addierst Du die Werte denn bzw. was soll dabei rauskommen?
mfG mirage228 |
Re: TFileTime addieren
Die CPU Zeit eines Prozesses setzt sich zusammen aus der zeit, die er im Kernel-Mode und User-Mode war. Deswegen muss ich sie addieren.
|
Re: TFileTime addieren
Hi,
Also in meiner D7 W32-SDK Hilfe steht zu FileTime Zitat:
mfG mirage228 |
Re: TFileTime addieren
Hm, und wie kopiere ich das in eine LARGE_INTEGER Struktur? Und wie bekomme ich davon dann wieder die Zeit?
|
Re: TFileTime addieren
Wie wärs z.B. damit:
Delphi-Quellcode:
type TLargeTime=record
case boolean of True: (DWlo:cardinal;DWHi:cardinal); False: (QW:int64); end; //kein Ahnung ob lo oder hi zuerst kommt, aber da wir bei little endian sind....
Delphi-Quellcode:
Edit: Wichtig ist, dass in ASM bei der Addtion der Hi DWords ein "adc" statt eines "add" genommen wird, um den Übertrag aus der zuvor erfolgten Addition (hier reicht add) der Lo DWords mitzunehmen.
procedure TForm1.Button1Click(Sender: TObject);
var a,b,c:TLargeTime; begin a.DWlo:=5; a.DWHi:=0; memo1.lines.add('A: '+inttostr(a.qw)); b.DWlo:=0; b.DWHi:=6; memo1.lines.add('B: '+inttostr(b.qw)); c.qw:=a.qw+b.qw; memo1.lines.add('C: '+inttostr(c.qw)); end; Edit2: Was die Unit Windows nicht so alles bietet :mrgreen:
Delphi-Quellcode:
PS: Irgendwie beist sich bei der Bezeichnung doch was:
_LARGE_INTEGER = record
case Integer of 0: ( LowPart: DWORD; HighPart: Longint); 1: ( QuadPart: LONGLONG); end; 1. DateTime -normalerweise double 2. dw* -steht eher für DWORD 3. Was ist dann DW*DATETIME? |
Re: TFileTime addieren
Zitat:
hier ![]() mfg Leonard |
Re: TFileTime addieren
Danke für den Link:
Delphi-Quellcode:
PS: Man sollte bei der CPU-Zeit auch nicht die Zeitzone berücksichtigen. :mrgreen:
CPUTime64.LowPart := ProcList.Items[i].KernelTime.dwLowDateTime + ProcList.Items[i].UserTime.dwLowDateTime;
CPUTime64.HighPart := ProcList.Items[i].KernelTime.dwHighDateTime + ProcList.Items[i].UserTime.dwHighDateTime; CPUTimeft.dwLowDateTime := CPUTime64.LowPart; CPUTimeft.dwHighDateTime := CPUTime64.HighPart; //CPUTime := (ProcList.Items[i].KernelTime.dwLowDateTime shl 32) + ProcList.Items[i].UserTime.dwHighDateTime; FileTimeToSystemTime(lft, st); GetTimeFormatW(LOCALE_SYSTEM_DEFAULT, TIME_FORCE24HOURFORMAT, @st, nil, TimeStr, SizeOf(TimeStr)); |
Re: TFileTime addieren
Hallo Michael,
du hast Sirius' Ergänzung offenbar überlesen: Zitat:
Das hier Zitat:
Gruß Hawkeye |
Re: TFileTime addieren
Zitat:
|
Re: TFileTime addieren
Deswegen musst du ja auch die einzelnen Teile den DWORD-Parts zuweisen und addierst dann die QWORD, so wie in meinem Beispiel.
|
Re: TFileTime addieren
Also so:
Delphi-Quellcode:
KernelTime64.LowPart := ProcList.Items[i].KernelTime.dwLowDateTime;
KernelTime64.HighPart := ProcList.Items[i].KernelTime.dwHighDateTime; UserTime64.LowPart := ProcList.Items[i].KernelTime.dwLowDateTime; UserTime64.HighPart := ProcList.Items[i].KernelTime.dwHighDateTime; CPUTime64.QuadPart := KernelTime64.QuadPart + UserTime64.QuadPart; CPUTimeft.dwLowDateTime := CPUTime64.LowPart; CPUTimeft.dwHighDateTime := CPUTime64.HighPart; FileTimeToSystemTime(CPUTimeft, st); GetTimeFormatW(LOCALE_SYSTEM_DEFAULT, TIME_FORCE24HOURFORMAT, @st, nil, TimeStr, SizeOf(TimeStr)); |
Re: TFileTime addieren
Wenn du den "Copy&Paste"-Fehler noch korrigierst, könnte es was werden:
Delphi-Quellcode:
Gruß Hawkeye
//UserTime64.LowPart := ProcList.Items[i].KernelTime.dwLowDateTime;
//UserTime64.HighPart := ProcList.Items[i].KernelTime.dwHighDateTime; UserTime64.LowPart := ProcList.Items[i].UserTime.dwLowDateTime; UserTime64.HighPart := ProcList.Items[i].UserTime.dwHighDateTime; |
Re: TFileTime addieren
:oops:
|
Re: TFileTime addieren
Ich häng mich hier mal hintendran, weil ich dasselbe Problem habe, und gerade damit nicht weiterkomme. Ich möchte bestimmen, wieviel Zeit eine Berechnung benötigt, und QueryPerformanceCounter scheint nicht auszureichen (da gibts manchmal Ausreißer, die ich mir nur dadurch erklären kann, dass ein anderer Prozess gerade rumgewerkelt hat). Mein Code sieht so aus:
Delphi-Quellcode:
Aber dabei kommen unsinnige Werte bei raus - sehr oft 0, und ab und zu andere Werte, aber dann recht oft derselbe (oder sogar immer). Irgendwas ist also falsch. Oder geh ich die Sache komplett falsch an?
function GetUsageTime: Int64;
var fCreationTime, fExitTime: TFileTime; fKernelTime, fUserTime: TFileTime; UserTime64, KernelTime64: _Large_Integer; begin GetProcessTimes(GetCurrentProcess, fCreationTime, fExitTime, fKernelTime, fUserTime); KernelTime64.LowPart := fKernelTime.dwLowDateTime; KernelTime64.HighPart := fKernelTime.dwHighDateTime; UserTime64.LowPart := fUserTime.dwLowDateTime; UserTime64.HighPart := fUserTime.dwHighDateTime; result := KernelTime64.QuadPart + UserTime64.QuadPart; end; Function GetAlgorithmTime: Int64; var s,e: Int64; begin s := GetUsageTime; // Zeit nehmen DoAlgorithm; // Berechnung ausführen e := GetUsageTime; // Zeit nehmen result := e-s; // Differenz ist das Ergbnis end; |
Re: TFileTime addieren
Hi,
wenn du ab und zu 0 als Ergebnis erhältst, dann könnte das daran liegen, dass sich die Laufzeit von DoAlgorithm nahe der Zeitauflösung (10 ms) bewegt. Um "einigermaßen verlässliche" Ergebnisse zu erzielen, wirst du wohl minimal 2 * 10 ms messen müssen. Ansonsten halte ich das mehrmalige Auftreten desselben Ergebnisses nicht unbedingt für einen Fehler. Bei geeigneten Testfällen wirst du bemerken, dass du durchaus variierende Zeiten erhältst - aus ähnlichen Gründen wie bei der Verwendung von QueryPerformanceCounter.
Delphi-Quellcode:
Wenn dein System gelegentlich eine Zeitsynchronisierung durchführt, dann sind die Ergebnisse natürlich verfälscht.
function GetUsageTime: TFileTime;
var ftDummy: TFileTime; ftKernelTime, ftUserTime: TFileTime; begin GetProcessTimes(GetCurrentProcess, ftDummy, ftDummy, ftKernelTime, ftUserTime); Result := TFileTime(Int64(ftKernelTime) + Int64(ftUserTime)); end; Freundliche Grüße |
Re: TFileTime addieren
Ist die Auflösung bei dem Ding nicht 100ns, also Zehntel Mikro-Sekunden? :gruebel:
Wenn ich deinen Code so abändere, also ohne die abschließende Konvertierung nach TFileTime
Delphi-Quellcode:
, dann erhalte ich wieder unsinnige Werte. Das heißt in 80-90% Null, und in den anderen Fällen 31200. Und das kann nicht sein.
function GetUsageTime: Int64;
var ftDummy: TFileTime; ftKernelTime, ftUserTime: TFileTime; begin GetProcessTimes(GetCurrentProcess, ftDummy, ftDummy, ftKernelTime, ftUserTime); Result := (Int64(ftKernelTime) + Int64(ftUserTime)); end; Ja, die Algorithmen sind recht schnell, mit QueryPerformanceCounter krieg ich raus, dass die je nach Eingabe nur wenige Dutzend µs brauchen - daher schlägt es ja auch durch, wenn Vista während eines Durchlaufs mal kurz guckt, was sonst noch so zu tun ist. Da sind dann halt ab und zu Ausreißer von ein paar hundert µs dabei, und die machen das Bild kaputt - auch wenn man über mehrere Durchläufe mittelt. |
Re: TFileTime addieren
Die Zeiteinheit von FileTime ist 100 ns - die Auflösung von GetProcessTimes() ist 10 ms, wie bei allen Windows Time Funktionen. Nur die High Precision Timer sind genauer.
|
Re: TFileTime addieren
...mit anderen Worten: Das Ding bringt mir gar nichts. Auch gut - dann muss ich die Ausreißer halt rausdiskutieren.
|
Re: TFileTime addieren
Vielleicht solltest du noch nach einer Erklärung für den Wert 31200 suchen.
|
Re: TFileTime addieren
Gegenfrage: Sind die 10ms ein verlässlicher konstanter Wert oder nur eine grobe Richtlinie? Gestern abend wurden aus den 31200 mal 78000, heute morgen sind es mal wieder 156001 und sporadisch 312002 (also genau das doppelte). Diese Werte mal 100 sind dann 3.120.000ns bis 15.600.100ns, also 3-15ms - das könnte dann die Timerauflösung sein.
Wenn der Algorithmus in einem Zeitfenster durchläuft, ist die Zeit 0, ansonsten ein Vielfaches des Timerintervalls. Klingt doch vernünftig, oder? |
Re: TFileTime addieren
10ms - halbwegs verlßlich, aber auch grobe Richtlinie.
wenn die Zeit kurz vor umschalten der Zeit ermittelt wird, dann sind es bis zum umschalten keine 10ms mehr, obwohl dieses angezeigt/errechnet wird.
Code:
10ms 20ms 30ms 40ms
* * * * | | > 20-10=10ms | | > 10-10=0ms | | > 30-10=20ms | | > 20-10=10ms |
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:35 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