CPU Usage unter PB 4.0

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Thalius
Beiträge: 476
Registriert: 17.02.2005 16:17
Wohnort: Basel / Schweiz

Beitrag von Thalius »

Kaeru Gaman hat geschrieben:@Thalius

welche Lib? /:->
Eine Meisterfrage!! Ehm - :? funzt bei dir ned ?

entweder liegts dran dass es schon fast 5 uhr morgens ist oder .. hrm
"...smoking hash-tables until until you run out of memory." :P
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag von Kaeru Gaman »

ne, funzt nulll. (mit 3 L)

also bitte, wenn du Libs installiert hast, schreib se dazu.

genau aus diesem Grund hab ich was gegen Libs...
der Progger der sie hat merkt garnicht mehr, wann sie wirken.

ich hatte vor zwei jahren mal son abschreckendes erlebnis,
wo ganz normale draw-befehle ne andere wirkung hatten,
bei nem kollegen, der zwei zusätzliche libs installiert hatte...

wenn ich Libs nutzen wollte, würd ich mir ne zweite Installation machen, wo ich Libs reinpacke.

...einfach, weil ich mir als moderator doof vorkommen würde,
wenn ich dastehe und sage "wus, den Befehl kennste nich?"
und dabei ist das irgendein Lib-kram, der im Basis-paket nich drin is....

...oder wenn standard-befehle plötzlich anderere ergebnisse bringen...
das is noch viel gruseliger, und kann mit Libs passieren.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Thalius
Beiträge: 476
Registriert: 17.02.2005 16:17
Wohnort: Basel / Schweiz

Beitrag von Thalius »

wus, den Befehl kennste nich?
genau den Moment hatte ich auch grade :oops: - mal sehn wo das drinnen steckt ... irgendwie wär jetzt ein Lib-Finder praktisch oder zumindet ne referenzinfo ( ich hab ne menge libs drauf ... /:-> )

EDIT: PBOSL / Misc
"...smoking hash-tables until until you run out of memory." :P
Benutzeravatar
Shardik
Beiträge: 746
Registriert: 25.01.2005 12:19

Beitrag von Shardik »

CpuUsage() ist eine Funktion, die entweder in Danilos PureTools UserLibrary oder in der PBOSL-Bibliothek PBOSL_CPUmonitor enthalten ist.
Agent
Beiträge: 296
Registriert: 13.09.2004 11:28
Kontaktdaten:

Beitrag von Agent »

Hallöche.

Ist denn vom Autor eine Version angedacht, die für MultiCore-Systeme gedacht ist? Wo ich sehen kann, welcher Kern wieviel ausgelastet ist? SpeedFan z.B. zeigt das an. Interessante Sache das ist :)

In der Art:

Code: Alles auswählen

Debug CpuUsage(CoreNo)
Sinnvollerweise in Ergänzung zu GetNoCPUCores() oder sowas.
Agent_Sasori
It's not a bug - it's a feature!
http://www.StephenKalisch.de | http://www.ria-tec.com | http://www.dirsync.de
Agent
Beiträge: 296
Registriert: 13.09.2004 11:28
Kontaktdaten:

Beitrag von Agent »

Ich nochmal.

Hab grad im engl. Forum dies gefunden, somit ist Part1 gelöst:

Code: Alles auswählen

  
Procedure.l  cpu_count()  ; Number of processors or cores
  Protected SI.SYSTEM_INFO
  GetSystemInfo_ (@SI)
  ProcedureReturn SI\dwNumberOfProcessors
EndProcedure 
Agent_Sasori
It's not a bug - it's a feature!
http://www.StephenKalisch.de | http://www.ria-tec.com | http://www.dirsync.de
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Beitrag von Helle »

Seit Windows 2000 liefert MS die PDH.DLL (Performance Data Helper) mit; zu finden im System32-Verzeichnis. Mit dieser DLL kann u.a. für alle verfügbaren Cores die Auslastung ermittelt werden. Hier ein schmuckloses Beispiel für 2 Cores (grafische Umsetzung ist nicht so mein Ding):

Code: Alles auswählen

;- CPU-Auslastung-Ermittlung mit der PDH.DLL, auch für Multi-Core-CPU´s 
;- "Helle" Klaus Helbing, 22.03.2008, PB4.10 
;- Soll nur schmucklos die einfache Machbarkeit zeigen! 

Global hQuery.l
Global RetVal.l
Global Core.l

Global SI.SYSTEM_INFO

;#PDH_CSTATUS_VALID_DATA = $0
#PDH_CSTATUS_NEW_DATA = $1

;ich mag keine Structuren...
Core = AllocateMemory(64)              ;für max. 4 Cores, 0-15=Counter, 16-31=PdhStatus, 32-63=dblValue 

Prototype.d ProtoValue(Para1.l, Para2.l)    ;CallFunction geht nicht wegen Double-Rückgabewert! 

Procedure.l  cpu_count()               ;Anzahl der Cores ermittlen 
  GetSystemInfo_ (@SI) 
  ProcedureReturn SI\dwNumberOfProcessors 
EndProcedure 

If OpenLibrary(0, "PDH.DLL")
  RetVal = CallFunction(0, "PdhOpenQuery", 0, 1, @hQuery)
  If RetVal
    MessageRequester("Fehler !", "Aufruf von PdhOpenQuery fehlgeschlagen!")  
  EndIf
 
  cpu_count()
 
  For i=0 To SI\dwNumberOfProcessors - 1
    RetVal = CallFunction(0, "PdhVbAddCounter", hQuery, "\Prozessor("+ Str(i) +")\Prozessorzeit (%)", Core+4*i)   ;Counter
    If RetVal
      MessageRequester("Fehler !", "Aufruf von PdhVbAddCounter für Core"+ Str(i) +" fehlgeschlagen!")  
    EndIf
  Next 
  
  Repeat 
    CallFunction(0, "PdhCollectQueryData", hQuery)
    Auslastung$=""
    For i=0 To SI\dwNumberOfProcessors - 1
      Value.ProtoValue = GetFunction(0, "PdhVbGetDoubleCounterValue")
      B.d = Value(PeekL(Core+4*i), Core+16+i<<2)
      Auslastung$ + "Auslastung Core" + Str(i)+" = "+ StrD(B, 2) + Space(20)
      If PeekL(Core+16+i<<2) > #PDH_CSTATUS_NEW_DATA  ;s.o.
        A = -1                         ;war kein gültiger Wert
        Break
      EndIf     
    Next 

    If A <> -1
      Debug Auslastung$
    EndIf
    Delay(500)
  ForEver 

  CallFunction(0, "PdhCloseQuery", hQuery)
  CloseLibrary(0)
EndIf 
Gruss
Helle

Edit: 22.03.2008: Ermittlung Core-Anzahl eingearbeitet
Zuletzt geändert von Helle am 03.02.2010 23:30, insgesamt 1-mal geändert.
Benutzeravatar
Helle
Beiträge: 566
Registriert: 11.11.2004 16:13
Wohnort: Magdeburg

Beitrag von Helle »

Hier eine praktische Anwendung mit Systray-Anzeige für einen Zwei-Corer:

Code: Alles auswählen

;- CPU-Auslastung-Ermittlung mit der PDH.DLL, Anzeige-Beispiel für 2 Cores
;- W2k, WXP, Vista(?) 
;- "Helle" Klaus Helbing, 24.03.2008, PB4.10 

Global hQuery.l
Global RetVal.l
Global Core.l
Global SI.SYSTEM_INFO
Global IData.b

;#PDH_CSTATUS_VALID_DATA = $0
#PDH_CSTATUS_NEW_DATA = $1

OpenWindow(0, 0, 0, 0, 0, "", #PB_Window_SystemMenu | #PB_Window_Invisible)    ;Window nicht anzeigen

;ich mag keine Structuren...
Core = AllocateMemory(332)             ;für max. 4 Cores, 0-15=Counter, 16-31=PdhStatus, 32-63=dblValue 

;-------- Alle Daten für Icon einlesen
Restore IconData
For x = 64 To 331
  Read IData
  PokeB(Core + x , IData)
Next x
;--------  

;-------- Erstmal ein Icon anzeigen
Icon = CatchImage(0, Core + 64)      ;Art und Grösse des Images werden aus den Header-Daten ermittelt
AddSysTrayIcon(0, WindowID(0), Icon) 
;--------

Prototype.d ProtoValue(Para1.l, Para2.l)    ;CallFunction geht nicht wegen Double-Rückgabewert! 

If OpenLibrary(0, "PDH.DLL")           ;MS-File in \System32 
  RetVal = CallFunction(0, "PdhOpenQuery", 0, 1, @hQuery)
  If RetVal
    MessageRequester("Fehler !", "Aufruf von PdhOpenQuery fehlgeschlagen!")  
  EndIf
 
  GetSystemInfo_(@SI)                  ;Anzahl der Cores ermittlen
 
  For i=0 To SI\dwNumberOfProcessors - 1
    RetVal = CallFunction(0, "PdhVbAddCounter", hQuery, "\Prozessor("+ Str(i) +")\Prozessorzeit (%)", Core+4*i)   ;Counter
    If RetVal
      MessageRequester("Fehler !", "Aufruf von PdhVbAddCounter für Core"+ Str(i) +" fehlgeschlagen!")  
    EndIf
  Next 
  
  Repeat 
    CallFunction(0, "PdhCollectQueryData", hQuery)
    Auslastung$=""
    Value.ProtoValue = GetFunction(0, "PdhVbGetDoubleCounterValue")
    For i=0 To SI\dwNumberOfProcessors - 1  ;Anzeige: Core0 oben, Core1 unten
      B.d = Value(PeekL(Core+4*i), Core+16+i<<2)
      B$ = StrD(B, 0)
 ;Auslastung$ + "Auslastung Core" + Str(i)+" = "+ StrD(B, 0) + "%" + Space(20)    
 
      If B$ = "100"
        B$ = "99"                      ;Anzeige nur zweistellig, 99 ist also auch 100
      EndIf
      
      B$=RSet(B$, 2, "0")              ;führende Null bei einstelligem Wert
          
      If PeekL(Core+16+i<<2) > #PDH_CSTATUS_NEW_DATA  ;s.o.
        A = -1                         ;war kein gültiger Wert
        Break
       Else
        E = Val(Right(B$, 1))
        For x = 0 To 6                 ;Einer-Werte      
          PokeB(Core + 235-36*i + (x << 2) , PeekB(Core + 262 + (E * 7) + x))
        Next x
         
        Z = Val(Left(B$, 1))
        For x = 0 To 6                 ;Zehner-Werte
          PokeB(Core + 234-36*i + (x << 2) , PeekB(Core + 262 + (Z * 7) + x))
        Next x 
      
        Icon = CatchImage(0, Core + 64)
        ChangeSysTrayIcon(0, Icon)        
      EndIf     
    Next 
 ;Debug Auslastung$
    Delay(500)
    Event = WindowEvent()
   
    If Event = #PB_Event_SysTray         ;Geduld, Abfrage-Anzeige kann mehrere Sekunden dauern!
      If EventType() = #PB_EventType_LeftDoubleClick
        Abfrage = MessageRequester("Intel-Core-Duo-Auslastungs-Anzeige", Space(26) + "Beenden ?", #PB_MessageRequester_YesNo)
        If Abfrage = #PB_MessageRequester_Yes     
          CloseWindow(0)
          End
        EndIf  
      EndIf
    EndIf
  
  Until Event = #PB_Event_CloseWindow

  CallFunction(0, "PdhCloseQuery", hQuery)
  CloseLibrary(0)
EndIf 

;--------------------------------------------------------------------------------------------------  
DataSection
;-------- Header eines 16x16-Icons mit 2 "Farben", bleibt konstant
IconData:
  Data.b  0, 0, 1, 0, 1, 0, 16, 16, 2, 0 ,0 ,0, 0, 0, 176, 0  
  Data.b  0, 0, 22, 0, 0, 0, 40, 0, 0, 0, 16, 0, 0, 0, 32, 0
  Data.b  0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 128, 0, 0, 0, 0, 0
  Data.b  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  Data.b  0, 0, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 
  Data.b  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  Data.b  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  Data.b  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  Data.b  0, 0, 0, 0, 0, 0
;-------- Ab hier den "Rest" der Icon-Datei mit Null auffüllen, nimmt dann die Bit-Muster
;-------- der Ziffern auf bzw. füllt den Abstand zwischen obere und untere Ziffern (255) aus
;-------- Auffüllen mit Null, weil die Ziffern-Werte durch Null-Words getrennt werden  
  Data.b  0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  Data.b  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  Data.b  0, 0, 255, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0
  Data.b  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  Data.b  0, 0, 0, 0, 0, 0
;-------- Bit-Muster der Ziffern 0 bis 9   
  Data.b  195, 189, 189, 189, 189, 189, 195    ;Ziffer 0 
  Data.b  227, 247, 247, 247, 247, 199, 231    ;Ziffer 1
  Data.b  193, 191, 191, 193, 253, 253, 131    ;Ziffer 2 
  Data.b  131, 253, 253, 195, 253, 253, 131    ;Ziffer 3
  Data.b  247, 247, 247, 129, 183, 183, 191    ;Ziffer 4   
  Data.b  131, 253, 253, 131, 191, 191, 129    ;Ziffer 5
  Data.b  195, 189, 189, 131, 191, 191, 195    ;Ziffer 6
  Data.b  239, 247, 247, 251, 253, 189, 129    ;Ziffer 7
  Data.b  195, 189, 189, 195, 189, 189, 195    ;Ziffer 8
  Data.b  195, 253, 253, 193, 189, 189, 195    ;Ziffer 9
EndDataSection
Wegen der Begrenzung auf 2 Ziffern bedeutet Anzeige (in Prozent) "99" auch "100", was aber wohl verschmerzbar ist.

Gruß
Helle
Zuletzt geändert von Helle am 03.02.2010 23:29, insgesamt 1-mal geändert.
Agent
Beiträge: 296
Registriert: 13.09.2004 11:28
Kontaktdaten:

Beitrag von Agent »

Hallo Helle.

Sehr schönes Beispiel. Danke!
Ich war auch schon im engl. Forum. Da beisst sich jemand auch die Zähne an sowas aus. Aber Dein Beispiel ist kurz und funktioniert. Top!
Agent_Sasori
It's not a bug - it's a feature!
http://www.StephenKalisch.de | http://www.ria-tec.com | http://www.dirsync.de
Agent
Beiträge: 296
Registriert: 13.09.2004 11:28
Kontaktdaten:

Beitrag von Agent »

Update:

Hab gerade nochmal geschaut, Dein Code ist auch schon bis dahin gewandert über das Osterwochenende. :)
Agent_Sasori
It's not a bug - it's a feature!
http://www.StephenKalisch.de | http://www.ria-tec.com | http://www.dirsync.de
Antworten