CPU Auslastung beim QuadCore
-
Hi,
ich habe ja schon diesen Artikel gefunden: http://www.c-plusplus.net/forum/viewtopic-var-p-is-1177579.html
So nutze ich das auch..
so, jetzt aber zu meinem Problem:
Ich habe einen QuadCore und möchte die CPU-Last pro Core ermitteln. Aber irgendwie funzt das nicht richtig. Der Wert für Core1 und Core2 stimmt, aber der Wert für Core3 + Core4 ist immer das gleiche für Core2.. Ich hab schon das halbe Netz durchsucht...
Weiß jemand Rat?
Machine
-
Welche der beiden Varianten hast Du verwendet? WMI? Damit sollte es gehen...
-
oh ich sehe grad, dass ich wohl doch eine andere variante hab... is schon ne weile her
hier mal die files:.h:
#pragma once #ifndef __CPULOAD_H__ #define __CPULOAD_H__ class CCpuLoad { public: CCpuLoad(); virtual ~CCpuLoad(); protected: int CpuInit(); // Initialisierung int CpuExit(); // Deinitialisierung public: int GetCpuCount(); // CPU-Anzahl abfragen int UpdateCpu(); // CPU-Auslastungsdaten holen int GetCpuLoad(unsigned uCpu); // CPU-Auslastungs für eine CPU abfragen }; #endif.cpp:
#include <windows.h> #include "CpuLoad.h" #define PROCESSOR_IDX 238 #define CPU_USAGE_IDX 6 static HKEY hWin9xKey = 0; static BOOL bIsWinNt = 0; static DWORD dwDataSize = 0; static DWORD dwWin9xUsage = 0; static __int64 *pCounterAct = 0; static __int64 *pCounterPre = 0; static __int64 iSysTimeAct = 1; static __int64 iSysTimePre = 0; static unsigned uCpuCount = 0; static union { PERF_DATA_BLOCK *o; BYTE *b; }pData; //--------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------- CCpuLoad::CCpuLoad() { CpuInit(); } //--------------------------------------------------------------------------------------- CCpuLoad::~CCpuLoad() { CpuExit(); } //--------------------------------------------------------------------------------------- //***************************************************************************** //* //* CpuUpdate //* //***************************************************************************** // Holt die neuesten Daten für die CPU-Auslastung // Ergibt 1 wenn ok sonst 0 int CCpuLoad::UpdateCpu() { DWORD dwSize; int iError; unsigned u; union { PERF_OBJECT_TYPE *o; BYTE *b; }pType; union { PERF_COUNTER_DEFINITION *o; BYTE *b; }pCounter; union { PERF_INSTANCE_DEFINITION*o; BYTE *b; }pInstance; union { PERF_COUNTER_BLOCK *o; BYTE *b; }pBlock; for(;;) { dwSize = dwDataSize; iError = RegQueryValueEx( HKEY_PERFORMANCE_DATA, "238", 0, 0,pData.b,&dwSize); if( iError != ERROR_MORE_DATA ) break; dwDataSize += 256; if( pData.o ) delete pData.o; pData.b = new BYTE[dwDataSize]; } if( iError != ERROR_SUCCESS || !pData.o ) { if( pData.o ) delete pData.o; return 0; } pType.b = ( (BYTE*)pData.o ) + pData.o->HeaderLength; for( u = 0; u < pData.o->NumObjectTypes; u++ ) { if( pType.o->ObjectNameTitleIndex == PROCESSOR_IDX ) break; pType.o += pType.o->TotalByteLength; } if( u >= pData.o->NumObjectTypes ) { delete pData.o; return 0; } if( ! uCpuCount && pType.o->NumInstances > (int) uCpuCount ) { uCpuCount = pType.o->NumInstances; pCounterAct = new __int64[uCpuCount*2]; pCounterPre = pCounterAct+uCpuCount; } pCounter.b = pType.b + pType.o->HeaderLength; for( u = 1; u < pType.o->NumCounters; u++ ) { if( pCounter.o->CounterNameTitleIndex == CPU_USAGE_IDX ) break; pCounter.b += pCounter.o->ByteLength; } if( u >= pType.o->NumCounters ) { delete pData.o; return 0; } pInstance.b = pType.b + pType.o->DefinitionLength; for( u = 0; (int) u < pType.o->NumInstances; u++ ) { pBlock.b = pInstance.b + pInstance.o->ByteLength; pCounterPre[u] = pCounterAct[u]; pCounterAct [u] =* (__int64*)( pBlock.b + pCounter.o->CounterOffset ); pInstance.b = pBlock.b + pBlock.o->ByteLength; } iSysTimePre = iSysTimeAct; SystemTimeToFileTime(&pData.o->SystemTime,(LPFILETIME)&iSysTimeAct); if( iSysTimePre == iSysTimeAct ) iSysTimeAct++; return 1; } //--------------------------------------------------------------------------------------- //***************************************************************************** //* //* CpuInit //* //***************************************************************************** // Initialisiert die CPU-Auslastungsberechnung // Ergibt 1 wenn ok sonst 0 int CCpuLoad::CpuInit() { DWORD dwVersion; dwVersion = GetVersion(); dwVersion = ( ( dwVersion & 0xFF00 ) >> 8 ) | ( ( dwVersion & 0x00FF ) << 8 ); if( dwVersion >= 0x0500 || dwVersion == 0x0400 || dwVersion == 0x0300 ) bIsWinNt = TRUE; if(!UpdateCpu()) return 0; return 1; } //--------------------------------------------------------------------------------------- //***************************************************************************** //* //* CpuExit //* //***************************************************************************** // Gibt alle Speicherbereiche wieder frei // Ergibt 1 wenn ok sonst 0 int CCpuLoad::CpuExit() { dwDataSize = 0; uCpuCount = 0; if(pCounterAct) { delete pCounterAct; pCounterAct = 0; pCounterPre = 0; } if( pData.b ) { delete pData.b; pData.b = 0; } if( hWin9xKey ) { int iError; HKEY hKey; DWORD dwSize,dwType; RegCloseKey(hWin9xKey); hWin9xKey = 0; iError=RegOpenKeyEx(HKEY_DYN_DATA,"PerfStats\\StopStat",0,KEY_ALL_ACCESS,&hKey); if( iError != ERROR_SUCCESS ) return 0; dwSize = sizeof(DWORD); RegQueryValueEx(hKey,"KERNEL\\CPUUsage",0,&dwType,(LPBYTE)&dwWin9xUsage,&dwSize); RegCloseKey(hKey); } return 1; } //--------------------------------------------------------------------------------------- //***************************************************************************** //* //* CpuLoad //* //***************************************************************************** // Ergibt die aktuelle CPU-Auslastung (0 bis 1024) // // uCpu : Ist die Nummer der CPU // // Danmit das funktioniert muss zuvor eine Zeit gewartet werden // und CpuUpdate aufgerufen werden // z.B. Sleep(1000); // CpuUpdate(); // CpuLoad(0); // CpuLoad(1); // ... int CCpuLoad::GetCpuLoad(unsigned uCpu) { __int64 iValue; int iLoad; if(uCpu>=uCpuCount) return -1; if(!bIsWinNt) // Windows 95/98 { if(!hWin9xKey) return -1; iLoad = (dwWin9xUsage<<10) / 100; } else { // Windows NT/2000/XP iValue = pCounterAct[uCpu] - pCounterPre[uCpu]; iValue <<= 10; iValue /= iSysTimeAct - iSysTimePre; iLoad = 1024 - (int) iValue; } if( iLoad < 0 ) iLoad=0; if( iLoad > 1024 ) iLoad = 1024; return iLoad; } //--------------------------------------------------------------------------------------- //***************************************************************************** //* //* CpuCount //* //***************************************************************************** // Gibt die Anzah aller CPU's int CCpuLoad::GetCpuCount() { SYSTEM_INFO sInfo; if(!uCpuCount) CpuInit(); GetSystemInfo(&sInfo); if( uCpuCount < sInfo.dwNumberOfProcessors ) return uCpuCount; return sInfo.dwNumberOfProcessors; } //--------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------
-
also ich bekomme bei GetCPUCount definitiv immer nur 2 raus, obwohl ich nen quadcore hab..
hat jemand nen link zu der sache mit wmi?
-
Was für Betriebssystem hast Du?
Je nach BS kann es sein, daß es nur 2 CPUs unterstützt...
-
sorry, das hätte ich natürlich schreiben können
das ist vista 32bit. im taskmanager wird die last jedes einzelnen cores angezeigt. iwi muss es also gehen 
-
Ich behaupte mal, die Anweisung in CCpuLoad::GetCpuCount()
if( uCpuCount < sInfo.dwNumberOfProcessors ) return uCpuCount;ist vermutlich der Übeltäter, daß als Ergebnis weniger als die tatsächliche CPU-Anzahl angegeben wird.
Martin
-
Mmacher schrieb:
Was für Betriebssystem hast Du?
Je nach BS kann es sein, daß es nur 2 CPUs unterstützt...Welches BS unstützt denn bitte, wenn es schon 2 CPU's unterstützt, keine 4? (rhetorisch
)
Das ziehlt doch eh aufs Multitasking/Multithreading, was Windows ja nun schon n bissl länger kann
.
-
CodeFinder schrieb:
Welches BS unstützt denn bitte, wenn es schon 2 CPU's unterstützt, keine 4? (rhetorisch
)Schon klar, rein rhetorisch
.
Lösung: Im Prinzip alle BS auf der WinNT-Schiene.
Hinweis: Oft stehen sogar auf den Aufklebern mit den Seriennummern der Zusatz "1-2 CPU", insbesondere in Verbindung mit Win2000 Pro.Warum? Das sind einfach marketingpolitische Abstufungen seitens Mikrosoft: "Wer mehr CPUs nutzen möchte, soll bitteschön die höherwertigen Editionen kaufen."
Oder auf marketingdeutsch: "skalierbare Lösungen"
Beispiel: WinServer2003 Datacenter kann bis 32 CPUs unterstützen (bzw. 64 CPUs in der x64-Edition), WinServer2003 Standard kann 4 CPUs, WinServer2003 Web dagegen nur Dual CPUs.
Früher (auf jeden Fall bis Win2000) war Anzahl CPU = Anzahl Cores, heute (z.B. Vista) ist Anzahl CPU = Anzahl physikalischer Prozessoren, unabhängig von der Core-Anzahl des jeweiligen Prozessors.Übrigens, das gleiche Phänomen kannst Du auch bei der nutzbaren RAM-Verwertung beobachten, guck Dir die aktuell verschiedenen Vista-Editionen an (Link habe ich nicht parat), sie können je nach Edition vershieden stark die CPUs und RAMs nutzen.
Martin