Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   adCpuUsage.GetCPUCount bei XE2 64bit immer 0 (https://www.delphipraxis.net/175171-adcpuusage-getcpucount-bei-xe2-64bit-immer-0-a.html)

NooL 3. Jun 2013 20:17

adCpuUsage.GetCPUCount bei XE2 64bit immer 0
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,

bräuchte mal ne Hilfe.

die UNit adCpuUsage bietet die Funktion GetCPUCount (z.B. Label1.Caption := IntToStr( GetCPUCount ) !

Bei XE2 64bit kommt als CPU-Count immer 0 !!!

Wird es als 32bit übersetzt, wird bei meiner 8-Kern (vermutlich) korrekt 9 angezeigt !

Kann mir jemand helfen, dass die UNIT adCpuUsage auch mit 64bit den richtigen Wert ausliest ?

Danke.

Amateurprofi 3. Jun 2013 23:31

AW: adCpuUsage.GetCPUCount bei XE2 64bit immer 0
 
Ich mache das so (und das funktioniert bei mir sowohl unter 32 Bit wie auch 64 Bit):

Delphi-Quellcode:
FUNCTION GetCpuCount:integer;
var SysInfo:TSystemInfo;
begin
   GetSystemInfo(SysInfo);
   result:=SysInfo.dwNumberOfProcessors;
end;

NooL 4. Jun 2013 06:36

AW: adCpuUsage.GetCPUCount bei XE2 64bit immer 0
 
Danke für die Antwort.

Das mache ich sonst auch so:
Zitat:

FUNCTION GetCpuCount:integer;
var SysInfo:TSystemInfo;
begin
GetSystemInfo(SysInfo);
result:=SysInfo.dwNumberOfProcessors;
end;
Aber ich möchte bei adCpuUsage nicht nur die Funktion GetCPUCount
nutzen, sondern in meinem Programm für bis zu 32 Kerne auch
die GetCPUUsage-Funktion. Da GetCPUUsage intern in adCpuUsage.pas
auf GetCPUCount aufbaut, ist es notwendig, diese mit zu nutzen.

Sorry, hab dies leider im Titel versäumt mit zu erwähnen. :oops:

Also 32bittig gehts in XE2 und 64bittig leider nicht.

Ich vermute mal, dass eine Typenumwandlung in adCpuUsage.pas
dafür verantwortlich ist, da die Unit ja schon recht alt ist.
Die Abschnitte $IFDEF Type und die Win9x-Breiche könnten bestimmt
für XE2 um einiges bereinigt und einige Typ-Umwandlungen
vereinfacht werden.
Leider reicht mein Wissen (noch) nicht aus, um das Problem
in adCpuUsage.pas zu erkennen.
Bin nicht so der gelernte Profi in Sachen Delphi. :?

Für weitere Hilfe bin ich echt dankbar . :-D

NooL 4. Jun 2013 18:51

AW: adCpuUsage.GetCPUCount bei XE2 64bit immer 0
 
Habs selbst gelöst.

Code:
    TPERF_OBJECT_TYPE = record
        TotalByteLength : DWORD;
        DefinitionLength : DWORD;
        HeaderLength : DWORD;
        ObjectNameTitleIndex : DWORD;
        ObjectNameTitle : DWORD;        // bei 64bit DWORD
//        ObjectNameTitle : LPWSTR;     // bei 32bit LPWSTR
        ObjectHelpTitleIndex : DWORD;
        ObjectHelpTitle : DWORD;        // bei 64bit DWORD
//        ObjectHelpTitle : LPWSTR;     // bei 32bit LPWSTR
        DetailLevel : DWORD;
        NumCounters : DWORD;
        DefaultCounter : Longint;
        NumInstances : Longint;
        CodePage : DWORD;
        PerfTime : TInt64;
        PerfFreq : TInt64;
    end;

    PPERF_OBJECT_TYPE = ^TPERF_OBJECT_TYPE;

type
    TPERF_COUNTER_DEFINITION = record
        ByteLength : DWORD;
        CounterNameTitleIndex : DWORD;
        CounterNameTitle : DWORD;      // bei 64bit DWORD
//        CounterNameTitle : LPWSTR;   // bei 32bit LPWSTR
        CounterHelpTitleIndex : DWORD;
        CounterHelpTitle : DWORD;      // bei 64bit DWORD
//        CounterHelpTitle : LPWSTR;   // bei 32bit LPWSTR
        DefaultScale : Longint;
        DetailLevel : DWORD;
        CounterType : DWORD;
        CounterSize : DWORD;
        CounterOffset : DWORD;
    end;

    PPERF_COUNTER_DEFINITION = ^TPERF_COUNTER_DEFINITION;
Oben genannte Änderungen müssen durchgeführt werden, damit es
unter der Zielplattform Win64 funktioniert.
Habe es im Internet in einer WinPerf.h gefunden.

Vielleicht konnte ich auch anderen damit helfen, falls bedarf besteht. :thumb:

Gruß Nool

Luckie 5. Jun 2013 11:25

AW: adCpuUsage.GetCPUCount bei XE2 64bit immer 0
 
Unter 32-Bit ist es eine nullterminierende Zeichenkette und unter 64-Bit eine Ganzzahl? Sehe ich das richtig?

NooL 5. Jun 2013 13:31

AW: adCpuUsage.GetCPUCount bei XE2 64bit immer 0
 
Jupp...

die genaue Info steht zum Beispiel hier:

http://dev.stackheap.com/trac/kuiper...lude/WinPerf.h

Code:
#ifdef _WIN64
 DWORD          ObjectNameTitle;   // Should use this as an offset
#else
 LPWSTR         ObjectNameTitle;   // Initially NULL, for use by
                                   // analysis program to point to
                                   // retrieved title string
#endif

#ifdef _WIN64
 DWORD          ObjectHelpTitle;   // Should use this as an offset
#else
 LPWSTR         ObjectHelpTitle;   // Initially NULL, for use by
                                   // analysis program to point to
                                   // retrieved title string
#endif
Bis zu 32 Kerne kann ich jetzt per Gauge anzeigen. Was mich nur
noch ein bisschen wundert, das GetCPUUsage auch negative Werte
liefert ??? Jedoch die Anzeige entspricht dem des Task Managers.

Weiß da jemand etwas darüber, ob das bei dem Auslesen der
TPERF_DATA_BLOCK.SystemTime normal ist, mit den Negativwerten ???

Gruß

GPRSNerd 5. Jun 2013 15:06

AW: adCpuUsage.GetCPUCount bei XE2 64bit immer 0
 
Ich habe mal ein anderes Tool und den Taskmanager mit CPU-Aussteuerung für alle Kerne gegen die Demo laufen lassen und es sieht für mich so aus, als ob immer die höchste CPU (in meinem Fall #4) den Durchschnittswert ausgibt.
CPU #0 bis #3 sind die einzelnen Kerne.
Kann das jemand bestätigen?

(getestet unter Win7 64bit Ultimate, kompiliert mit XE4 32bit)

NooL 5. Jun 2013 18:49

AW: adCpuUsage.GetCPUCount bei XE2 64bit immer 0
 
Ja, so ist es. Bei meiner 8 Kerner werden 9 Werte ( 0 - 8 ) ausgelesen.
0-7 sind die 8 Kerne und der 9.Wert ( 8 ) soll der Durchschnitt
aller Kerne sein.
Diesen zusätzlichen Wert blende ich aus bzw. benutze ich nicht.
Habe es auch noch bei einer 4 Kern, 2 Kern und bei einem Server mit
32 Kernen ausprobiert. Dort war es auch so.

Was mich nur stutzig macht, sind die negativen Werte die GetCPUUsage
zurück gibt??? Die Frage ist, ist das so gewollt, oder doch noch ein
weiterer Fehler ??? :roll:
Code:
result:=1-(_Counters[index] - _PrevCounters[index])/(_SysTime-_PrevSysTime);
Kennt sich damit jemand aus bzw. kann das einer der adCpuUsage auch nutzt, mal
irgendwie überprüfen ??? :idea:

GPRSNerd 5. Jun 2013 19:50

AW: adCpuUsage.GetCPUCount bei XE2 64bit immer 0
 
Zitat:

Zitat von NooL (Beitrag 1217583)
Was mich nur stutzig macht, sind die negativen Werte die GetCPUUsage
zurück gibt??? Die Frage ist, ist das so gewollt, oder doch noch ein
weiterer Fehler ???

Zu den Zeiten, wenn GetCPUUsage negative Werte zurückgibt, zeigen alle anderen Programme 0 an, dementsprechend runde ich die Werte auf Minimal 0 auf:
Delphi-Quellcode:
procedure TTestForm.TimerTimer(Sender: TObject);
var
  i: Integer;
  Last: Double;
begin
  CollectCPUData;
  MInfo.Lines.BeginUpdate;
  for i:=0 to GetCPUCount-1 do
  begin
    Last := GetCPUUsage(i)*100;
    if Last < 0 then Last := 0;

    if i=GetCPUCount-1 then //letzte CPU zeigt Durchschnitt (Gesamtlast)
      MInfo.Lines[i+1]:=Format('Durchschnitt: %5.2f%%', [Last])
    else
      MInfo.Lines[i+1]:=Format('CPU #%d:      %5.2f%%', [i, Last]);
  end;
  MInfo.Lines.EndUpdate;
end;

NooL 5. Jun 2013 21:17

AW: adCpuUsage.GetCPUCount bei XE2 64bit immer 0
 
Okay, danke für die Rückinfo:
Zitat:

dementsprechend runde ich die Werte auf Minimal 0 auf
Dann werde ich es so ähnlich umsetzen. :thumb: Besten Dank.


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:21 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