![]() |
Windows.GetTickCount64 auch unter Windows XP?
Heute habe ich das erste mal von Windows.GetTickCount64 gehört. Kann man das auch unter Windows XP nutzen oder benötigt man für Windows XP diesen Workaround?
![]() |
AW: Windows.GetTickCount64 auch unter Windows XP?
Was steht dort
![]() Also ja, vor Windows 8 gibt es das nicht und man braucht was Anderes. |
AW: Windows.GetTickCount64 auch unter Windows XP?
Heißt also das Andere ist dein Code da oben? :P
Braucht man denn irgendwelche Fallunterscheidungen je nach Betriebssystem oder kann man einfach die Unit oben nutzen? Wenn ich das hier richtig verstehe sollte das doch schon als "Fallunterscheidung" reichen
Delphi-Quellcode:
GetTickCount64 := GetProcAddress(GetModuleHandle('Kernel32.dll'), 'GetTickCount64'); // Für alles ab Windows 8
if @GetTickCount64 = nil then // für alles vor Windows 8 // |
AW: Windows.GetTickCount64 auch unter Windows XP?
Jupp, entweder die WinAPI oder wenn nicht existent, dann wird automatisch die Ersatzfunktion verwendet.
|
AW: Windows.GetTickCount64 auch unter Windows XP?
Hier gibt es dazu noch einen Artikel mit Workarounds:
![]() |
AW: Windows.GetTickCount64 auch unter Windows XP?
Zacherl, dein Artikel hat mich neugierig gemacht und die Schnelligkeit von _GetTickCount64 geprüft.
bei 999.999 aufrufen dauert die Ausführung schon knapp 400ms. Windows.GetTickCount54 braucht nur knapp 25ms. |
AW: Windows.GetTickCount64 auch unter Windows XP?
Welche der Versionen hast du denn verwendet? Die mit dem manuellen Overflow Check sollte die Performance nicht nennenswert verschlechtern (laut Artikel ist sie ja angablich sogar besser als die native
![]() |
AW: Windows.GetTickCount64 auch unter Windows XP?
Ich habe himitu's Version (Link erster Beitrag) verwendet. Mit den anderen kann ich nichts anfangen, da es kein Delphi-Code ist.
Mehr als das hier bekomme ich nicht hin und selbst das ist bestimmt noch falsch
Delphi-Quellcode:
var
high, lastLow: Int64; begin high := 0; low := GetTickCount(); if lastLow > low then // high += 0x100000000I64; ... lastLow = low; // return high | (ULONGLONG)low; end; |
AW: Windows.GetTickCount64 auch unter Windows XP?
Sollte in etwa so aussehen:
Delphi-Quellcode:
Ist etwas weniger als halb so performant wie die native Funktion, aber immer noch deutlich schneller als mit
threadvar
High: UInt64; LastLow: Cardinal; function _GetTickCount64: UInt64; inline; var Low: Cardinal; begin Low := GetTickCount; if (LastLow > Low) then begin High := High + $0000000100000000; end; LastLow := Low; Result := High or Low; end; ![]()
Delphi-Quellcode:
auch durch
threadvar
Delphi-Quellcode:
ersetzen - dann ist die Funktion in etwa gleich schnell wie die native Variante.
var
|
AW: Windows.GetTickCount64 auch unter Windows XP?
Ich habe das jetzt so gelößt
Delphi-Quellcode:
unit uGetTickCount64;
interface uses Winapi.Windows, System.SysUtils; threadvar High: UInt64; LastLow: Cardinal; type TGetTickCount = class public class function GetTickCount64: UInt64; inline; end; implementation class function TGetTickCount.GetTickCount64: UInt64; var Low: Cardinal; begin if System.SysUtils.TOSVersion.Major >= 6 then // alles ab Windows Vista Result := Winapi.Windows.GetTickCount64 else // alles vor Windows Vista begin Low := GetTickCount; if (LastLow > Low) then High := High + $0000000100000000; LastLow := Low; Result := High or Low; end; end; end. |
AW: Windows.GetTickCount64 auch unter Windows XP?
PS: Klassen sind optional und nicht immer notwendig oder sinnvoll :duck:
|
AW: Windows.GetTickCount64 auch unter Windows XP?
Zitat:
Wenn es doch umbedingt in einer "Klasse" sein soll, dann klatsch noch ein
Delphi-Quellcode:
vor das
static
Delphi-Quellcode:
und mach das
inline
Delphi-Quellcode:
zu
class
Delphi-Quellcode:
, dann sparst du dir noch ein (verstecktes) Funktionsargument und zusätzlich die (nicht benötigten) RTTI-Infos für die Klasse. Und dann kannst du auch die
record
Delphi-Quellcode:
s direkt noch mit in den Record übernehmen.
threadvar
|
AW: Windows.GetTickCount64 auch unter Windows XP?
Das weiß ich =)
Ich benutze sie sehr gerne und überall in meinen Units. Wenn ich irgendwo im Code stehen habe
Delphi-Quellcode:
dann kann das von Winapi.Windows kommen oder aus der eigenen Unit - kommt ganz auf die Reihenfolge in den uses an.
GetTickCount64
Wenn ich aber
Delphi-Quellcode:
sehe weiß ich genau wo es herkommt.
TGetTickCount.GetTickCount64
Edit Klar ich kann auch ohne Klasse arbeiten und schreibe
Delphi-Quellcode:
aber dann bekomme ich ggf. Probleme wenn ich die Unit mal umbenennen will.
MeineUnit.GetTickCount64
So?
Delphi-Quellcode:
type
TGetTickCount = record public class function GetTickCount64: UInt64; static; inline; end; |
AW: Windows.GetTickCount64 auch unter Windows XP?
Delphi-Quellcode:
type
TTest = record strict private class threadvar High: UInt64; class threadvar LastLow: Cardinal; public class function GetTickCount64: UInt64; static; inline; end; { TTest } class function TTest.GetTickCount64: UInt64; begin // ... end; |
AW: Windows.GetTickCount64 auch unter Windows XP?
Zitat:
Delphi-Quellcode:
-Bedingung benutzt wird: GetTickCount64 gibt's ab Vista, nicht erst ab Win8. Vermutlich haben deine Augen der Angabe "Windows Phone 8" zuviel Aufmerksamkeit geschenkt ;).
if
Grüße Dalai |
AW: Windows.GetTickCount64 auch unter Windows XP?
Zitat:
Durch die Änderung von class zu record habe ich sogar noch ein paar Compilerfehler bekommen an Stellen, wo ich static vergessen hatte hinzuzufügen. Habe dann direkt auch mal alle packed records in records umgeschrieben. Ich denke nun ist alles klar. |
AW: Windows.GetTickCount64 auch unter Windows XP?
Also habe ich das richtig verstanden, dass Du einfach nur die Ticks auslesen willst ? Wenn ja, wieso dann so kompliziert ?
Delphi-Quellcode:
Das sollte für rudimentäre Zwecke reichen. Willst Du ganz exaktes Messen veranstalten, da nimm doch die Routine von Agner Fog (Optimierungs Papst) :wink: :
function GetTicks : UInt64; register;
asm rdtsc {$IFDEF WIN64} shl rdx, 32 or rax, rdx {$ENDIF} end;
Delphi-Quellcode:
Um auf das "Tick" genau zu sein, müsstest Du dann zusätzlich die Funktion hintereinander aufrufen und die Differenz bilden. Bei späteren Messungen ist diese Differenz (verursacht von dem Funktionsaufruf) abzuziehen.
function GetTicks : UInt64;
asm {$IFDEF CPUX64} .NOFRAME // by Agner Fog push rbx // ebx is modified by cpuid sub rax, rax // 0 cpuid // serialize rdtsc // read time stamp counter into edx:eax shl rdx, 32 or rax, rdx // combine into 64 bit register push rax sub eax, eax cpuid // serialize pop rax // return value pop rbx ret {$ELSE} push ebx // ebx is modified by cpuid sub eax, eax // 0 cpuid // serialize rdtsc // read time stamp counter push eax push edx sub eax, eax cpuid // serialize pop edx pop eax pop ebx ret {$ENDIF} end; Gruß Thomas |
AW: Windows.GetTickCount64 auch unter Windows XP?
...und weil Windows immer noch kein
![]() Sherlock |
AW: Windows.GetTickCount64 auch unter Windows XP?
Zitat:
Eins ist klar. Die obere der beiden ASM-Funktionen gibt Quark zurück. GetTickCount64 gibt: 653.954.506 GetTick gibt zurück: 1.349.183.170.576.009 |
AW: Windows.GetTickCount64 auch unter Windows XP?
Naja "falsch" würde ich das nicht nennen. Das ist ungefär so, als würdest du eine Stopuhr für das Eierkochen nutzen. Je nachdem was, auf Deinem Rechner läuft, ist die Zeitspanne für ein und die selbe Routine immer unterschiedlich. Da erreichst Du eine Genauigkeit, die keine Aussagekraft besitzt. Unter Windows mußt Du immer mehrere Messungen durchführen um einen Trend zu erkennen. Eine Aussage wie "die Laufzeit ist 25 Timerticks" ist unter Windows schlicht Blödsinn.
Gruß K-H |
AW: Windows.GetTickCount64 auch unter Windows XP?
Ist vielleicht "Off-topic", aber
![]() Nehme ich mittlerweile lieber statt der GetTickCounts, ist auch CrossPlatform :stupid: Rollo |
AW: Windows.GetTickCount64 auch unter Windows XP?
Kann man demnach die oben genannten Routinen statt GetTickCount(64) verwenden oder eher nicht?
|
AW: Windows.GetTickCount64 auch unter Windows XP?
Zitat:
Früher (vielleicht auch teilweise noch heute) hatte jeder CPU-Kern seinen eigenen Tickcounter * Problem: Windowsch schiebt standardmäßig die Programme umher, also wenn du den ersten TickCount nimmst und mit einem zweiten verrechnest (Differenz), dann kann da schnell Mist raus kommen, wenn zwischendurch dein Programm (der Thread) auf einen anderen Kern verschoben wurde. Daher gingen viele CPU-Hersteller dazu über einen "virtuellen" globalen TickCount zu nehmen, der mit keinem der Kerne übereinstimmt. Außerdem werden häufig die CPUs/Kerne zur Laufzeit lastabhängig getacktet. Fazit: dieser der CPU-TickCount stimmt nicht mehr mit den Ticks (ausgeführten Aktionen auf dem Kern) der Kerne überein. Und bezüglich Echtzeitsystem ... jupp, jede Anwendung/Thread hat einen TimeSlot und wirt zwischendurch immer mal wieder pausiert, während andere Prozesse/Threads auf dem Kern rechnen dürfen. |
AW: Windows.GetTickCount64 auch unter Windows XP?
Zu RDTSC:
Zitat:
![]() ![]() |
AW: Windows.GetTickCount64 auch unter Windows XP?
Ich habe hier vier Beiträge gelöscht, die in einer völligen Entgleisung endeten.
|
AW: Windows.GetTickCount64 auch unter Windows XP?
ich nutz QueryPerformanceCounter immer wenn ich was benche, ich finde es sehr präzise.
Nur als vergleich gegen GetTickCount egal ob x86 oder x64. Als alternative halt. Ich hoffe der code ist mit neueren delphi versionen kompatibel.
Delphi-Quellcode:
{QueryPerformanceCounter uses the PC's clock counter just as GetTickCount, but it
reads the current value of the countdown register in the timer chip to gain more accuracy -- down to 1.193MHz (about 800ns). However, it takes 5 to 10us to call QueryPerformanceCounter, because it has to do several port I/O instructions to read this value. If you are running multiprocessor NT, QueryPerformanceCounter uses the Pentium cycle counter. You should not be using the raw value of QueryPerformanceCounter; you should always divide by QueryPerformanceFrequency to convert to some known time base. QueryPerformanceCounter doesn't run at the same rate on all machines. The example below shows how to use it in Delphi 3/4: } type TInt64 = TLargeInteger; var Frequency, lpPerformanceCount1, lpPerformanceCount2 : TLargeInteger; begin QueryPerformanceCounter(TInt64((@lpPerformanceCount1)^)); // activity to measure my_proc; QueryPerformanceCounter(TInt64((@lpPerformanceCount2)^)); QueryPerformanceFrequency(TInt64((@Frequency)^)); // this shows the time in ns ShowMessage(IntToStr(Round(1000000 * (lpPerformanceCount2.QuadPart - lpPerformanceCount1.QuadPart) / Frequency.QuadPart))); end; |
AW: Windows.GetTickCount64 auch unter Windows XP?
Hallo,
OK, Info zur Starter-Edition gelöscht. Kennt ja wohl jeder mittlerweise. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:59 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