![]() |
JCLCounter - High Performance Counter
Hallo Forum,
ich verwende seit einiger zeit (6Monate) den JCLCounter aus der JCL Lib. Damit versuche ich genaue Zeitmessungen durchzuführen. Ging immer...bis gestern. Seit gestern kann ich kein einziges Tool mehr starten ohne das die Exception ausgelöst wird: No high performance counters supported. Das würde bedeuten, das meine CPU sowas nicht unterstützt. Sinnlos...weil es über n halbes Jahr ging. Weiß jemand woran das liegen könnte? mfg, Marko :coder: |
Re: JCLCounter - High Performance Counter
Zitat:
|
Re: JCLCounter - High Performance Counter
zu faul um ne zeitmessung selber zu amchen? :-D
Ist doch viel einfacher als irgendeine Kompo zu nutzen...
Delphi-Quellcode:
Man sollte die Zeit dann evtl runden, weil ja durch den Gleitkommawert das ergebnis verfälsch wird...
var
freq,time1,time2: int64; begin QueryPerformanceFrequency(freq); QueryPerformanceCounter(time1); //Do Something QueryPerformanceCounter(time2); ShowMessage(FloatToStr((time2-time1)/freq)); |
Re: JCLCounter - High Performance Counter
Nuetzt aber wahrscheinlich nichts, wenn QueryPerformanceFrequency 0 zurueckliefert.
Pruef mal nach was diese Funktion zurueckliefert. Wenn wirklich 0 zurueckkommt, dann hat das Windows Update einen Fehler eingeschleppt. |
Re: JCLCounter - High Performance Counter
Zitat:
1. kann der Zeitoverhead für den Funktionsaufruf herausgerechnet werden 2. kann man mehr als nur eine Zeitmessung vornehmen. Ohne Kapselung in eine Klasse verliert man völlig den Überblick. 3. man kann die Zeit anhalten und die abgelaufene Zeit erst viel später anzeigen 4. dein code-Schnippsel prüft den Returnwert von QueryPerformanceFrequency nicht !! Aber egal, auch TJclCounter benützt QueryPerformanceCounter/Frequency.
Delphi-Quellcode:
Die MSDE sagt:
// hier der entscheidende Ausschnitt aus dem Sourcecode
if not QueryPerformanceFrequency(FFrequency) then // 'No high performance counters supported' raise EJclCounterError.CreateRes(@RsNoCounter); Zitat:
|
Re: JCLCounter - High Performance Counter
Zitat:
zu 4. sollte nur ein kurzes unvollständiges Beispiel sein... natüröich kann ich noch dies und das prüfen und verbessern |
Re: JCLCounter - High Performance Counter
Zitat:
Angenommen, du möchtest 10 verschiedene Zeiten messen. Ohne Kapselung in einer Klasse artet das doch in ein Gemetzel aus.
Delphi-Quellcode:
Jetzt könnte man natürlich einen Record für die Start und Stopzeit bauen und ein Array nutzen:
var
freq,time1Start,time1Stop,time2Start,time2Stop, time3Start,time3Stop, ...... : int64;
Delphi-Quellcode:
Der halbe Weg zur Klasse ist schon getan.
type
TTimeRec = record start, stop : Int64; end; var freq : int64; zeitliste : array[1..10] of TTimeRec;
Delphi-Quellcode:
// die objekt-orientierte Variante
// kein "herumgerechne", kein Aufruf von Low-Level-Funktionen // einfach, sauber & klar var zeitliste : array[1..10] of TJclCounter; begin zeitliste[1].Start; ... zeitlist[1].Stop; ... ShowMessageFmt('Zeit 1: %f',[zeitlist[1].ElapsedTime]); |
Re: JCLCounter - High Performance Counter
Liste der Anhänge anzeigen (Anzahl: 1)
creality, kannst du mal ein simples Testprogramm ausprobieren und das Ergebnis hier posten?
|
Re: JCLCounter - High Performance Counter
So ich mal wieder:
QueryPerformanceFrequency liefert komischerweise nicht 0 zurück. Und zu faul bin ich auch nich ne Zeitmessung selber zu schreiben...vielleicht schreib ich ja gleich noch den TCPIP Stack neu wenn ich grad dabei bin :thumb: Ich hab aber den JCP in vielen meiner Tools verwendet und müsste ihn wieder rausnehmen wenn ich Ursache nicht finde...
Delphi-Quellcode:
procedure TForm1.button_3Click(Sender: TObject); var freq,time1,time2: int64; i,a : Integer; begin QueryPerformanceFrequency(freq); QueryPerformanceCounter(time1); for I := 0 to 10000000 do Inc(a); QueryPerformanceCounter(time2); ShowMessage(FloatToStr((time2-time1)/freq)); end; "Message = 0,0102" |
Re: JCLCounter - High Performance Counter
@ Robert: Getestet
Freq := 0; if not QueryPerformanceFrequency(Freq) then wird übersprungen...also keine Ausgabe. |
Re: JCLCounter - High Performance Counter
Das heisst mein Testprogramm gibt nichts aus.
Ruf doch mal den Installer der JCL auf und installiere einfach erneut. Vielleicht hilft das ja. Der Installer hat auf jeden Fall kein Problem damit immer wieder aufgerufen zu werden. |
Re: JCLCounter - High Performance Counter
@ Robert:
Jo dein Programm gibt nix aus. Die QueryPerformanceFrequency(Freq) ist nicht NULL und auch QueryPerformanceCounter(time) gibt ein INT64 zurück. JCL hab ich bereits mehrfach installiert, deinstalliert und manuell installiert. immer das gleiche. furchtbar :stupid: |
Re: JCLCounter - High Performance Counter
Neueste Version? Evtl. haben ja ältere JCL-Versionen hier eine Wanze eingebaut?
|
Re: JCLCounter - High Performance Counter
Kopier doch mal JclCounter.pas, fuege es in dein Projekt ein, builde dein Programm und geh mit dem Debugger in den Konstruktor und schaue nach was dort passiert.
|
Re: JCLCounter - High Performance Counter
An dem Update für Windows liegt es nicht, bei mir geht alles. Mach dein Windows mal platt.
|
Re: JCLCounter - High Performance Counter
Zitat:
Wir sollten die Ursache schon finden. Windows-Update ändern teilweise Systemeinstellung (wurde bei mir für die Internetzone "Trusted Sides" auch wieder gemacht und das auch nicht bei jedem Anwender. |
Re: JCLCounter - High Performance Counter
Zusammenfassung bisheriger Ergebnisse
Funktioniert. Zeit kann gemessen werden ohne Probleme.
Delphi-Quellcode:
Auszug aus dem JCL Counter:
// Start
procedure HiPerfCounter.Start; begin try QueryPerformanceFrequency(freq); QueryPerformanceCounter(time1); except on E:Exception do begin ShowMessage('HiPerfCounter reported an Error. QueryPerformanceCounter is not supported.'); end; end; end; Funktioniert nicht, obwohl hier genau das gleiche passiert: QueryPerformanceFrequency(FFrequency) liefert NULL zurück. WIESO?
Delphi-Quellcode:
constructor TJclCounter.Create(const Compensate: Boolean); const Iterations: Integer = 10000; var Count: Integer; TmpOverhead: Int64; begin inherited Create; {$IFDEF MSWINDOWS} if not QueryPerformanceFrequency(FFrequency) then raise EJclCounterError.CreateRes(@RsNoCounter); {$ENDIF MSWINDOWS} {$IFDEF LINUX} FFrequency := 100000; // 1 sec = 10E6 microseconds, therefore we have to divide by 10E5 {$ENDIF LINUX} FCounting := False; FOverhead := 0; ...................... .......... |
Re: JCLCounter - High Performance Counter
Mal den PEViewer der JCL uebersetzen und auf die EXEs ansetzen, aber eigentlich sollten genau die gleichen Funktionen eingelinkt werden.
Alternativ die JVCL und JCL deinstallieren und loeschen und dann wirkich alle Files aus dem Delphi-Verzeichnisbaum loeschen die mit Jcl oder Jv beginnen. Danach die Festplatte absuchen ob nicht noch andere Files mit diesen Prefixen rumliegen. Moeglichst auch loeschen. Nun JVL und JVCL von ![]() ![]() |
Re: JCLCounter - High Performance Counter
@ Robert:
Ich habe soeben die JCLCounter.pas n bisschen editiert. Vor dem call: if not QueryPerformanceCounter(FStart) then habe ich ne Testvariable eingefügt: Test : bool. Und jetzt kommts: test := QueryPerformanceCounter(FStart); gibt NICHT null zurück und siehe da...der Counter geht wieder. Ich verstehs aber nicht. Nach dem entfernen der Var geths trotzdem. Ich vermute aber...das es nicht daran lag sondern an irgendwas anderem. So kanns nicht weitergehen...ich werde mal deine Schrittliste abarbeiten und den ganzen Kram entfernen.
Delphi-Quellcode:
procedure TJclCounter.Start;
var test : Boolean; begin test := QueryPerformanceCounter(FStart); FCounting := True; FElapsedTime := 0; FOverallElapsedTime := 0; {$IFDEF MSWINDOWS} if not QueryPerformanceCounter(FStart) then raise EJclCounterError.CreateRes(@RsNoCounter); {$ENDIF MSWINDOWS} {$IFDEF LINUX} GetTimeOfDay(FTimeval, nil); FStart := FTimeval.tv_sec * 100000 + (FTimeval.tv_usec); {$ENDIF LINUX} end; |
Re: JCLCounter - High Performance Counter
I think we've met the same problem some days ago with delphi 2006 and JCL and we just found a simple way to solve it : you have to change your compiler settings to align record data on 4 bytes.
For Delphi 2006, Go to Project => Options => Compiler => Code generation and look for the "Field Record Alignment" with a combobox with possible values : "0,1,2,4,8". You have to choose 4 (8 also seems to work) and recompile all your project I do not know for other Delphi versions but it should be quite similar IMHO PS : Sorry for writing in english on a german forum :(. I hope someone could translate it to others people here |
Re: JCLCounter - High Performance Counter
Thanks for this hint! We will check the JCL if we can find a problem there. It may be a compiler bug though.
Der Hinweis ist das Projekt auf record alignment 4 bzw. 8 einzustellen und komplett neu zu erstellen. creality, kannst du mal {$ALIGN 4} in JclCounter.pas einfuegen und die JCL neu erstellen (einfach install.bat erneut ausfuehren). Am besten zwischen das erste uses und der Deklaration von TJclCounter. Alternativ {$IFDEF MSWINDOWS} function QueryPerformanceCounter(var lpPerformanceCount: Int64): BOOL; stdcall; external kernel32 name 'QueryPerformanceCounter'; function QueryPerformanceFrequency(var lpFrequency: Int64): BOOL; stdcall; external kernel32 name 'QueryPerformanceCounter'; {$ENDIF MSWINDOWS} In der implementation section von JclCounter.pas platzieren. Das Original in Windows.pas ist mit TLargeInteger deklariert und daher koennten die Probleme kommen. Wenn das nicht hilft, dann {$IFDEF MSWINDOWS} function QueryPerformanceCounter(lpPerformanceCount: Pointer): BOOL; stdcall; external kernel32 name 'QueryPerformanceCounter'; function QueryPerformanceFrequency(lpFrequency: Pointer): BOOL; stdcall; external kernel32 name 'QueryPerformanceCounter'; {$ENDIF MSWINDOWS} ausprobieren und die Aufrufe um ein @ vor dem Parameter ergaenzen. Bitte alle Varianten ausprobieren. Sollte die zweite Variante funktionieren, dann wird sie in die JCL uebernommen. |
Re: JCLCounter - High Performance Counter
Ok, ich werds ausprobieren. Heut Nachmittag sitz ich wieder am Rechner. Ich lasses Euch wissen!
In diesem Sinne, bis später. |
Re: JCLCounter - High Performance Counter
Hi, :wall: :wall: :wall:
auch ich habe hier das Problem mit dem Timer. Es gibt dazu bei MS einen Artikel in der Knowledge Base :896256 und ![]() ![]() Ich glaube in Zukunft können wir uns auf den Timer nicht mehr verlassen. Hier ist auch noch was zu den Thema ![]() Gruß MrOuzo |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:12 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 by Thomas Breitkreuz