2009-05-12 13 views
10

Sto lavorando su una piattaforma di profilatura multipiattaforma e vorrei aggiungere informazioni sul CPU (architettura/velocità di clock/core) e RAM (totale) al report di ogni sessione. Attualmente ho bisogno di indirizzare Windows e Unix, quindi ho bisogno di metodi per ottenere queste informazioni da entrambe le piattaforme, eventuali indizi?Come determinare l'hardware (CPU e RAM) su una macchina?

Modifica: Grazie per le ottime risposte, ora ho ottenuto l'architettura della CPU, il numero di CPU dei core e la memoria totale, ma mi manca ancora un clock per la CPU qualche idea per quello?

+0

la stringa risultante da __cpuinfo include clesspeed – bsruth

+0

@bsruth Grazie, ora vedo che è davvero nella marcatringa –

risposta

4

La CPU è facile. Utilizzare l'istruzione cpuid. Lascerò altri poster per trovare un modo portatile per determinare quanta RAM ha un sistema. :-)

Per i metodi specifiche per Linux, è possibile accedere /proc/meminfo (e /proc/cpuinfo, se non si può essere preso la briga di analizzare cpuid risposte).

+1

E presumibilmente come trovare le informazioni sulla CPU su un processore che non ha alcun tipo di istruzione CPUID? ;) (CPUID potrebbe anche dirvi quanti core ha il pacchetto del processore?) – araqnid

+1

Leggere: http://www.intel.com/design/processor/applnots/241618.htm (risposta breve: sì). Tutte le scommesse sono disattivate se la CPU è troppo vecchia per supportare cpuid, ma nessun sistema moderno ha questo problema. –

+1

Stavo pensando che non tutti i sistemi sono basati su processori con architettura i386. (Sebbene fosse consapevole che questa non era una situazione a cui l'OP era interessata) – araqnid

3

Su Linux è possibile analizzare/proc/cpuinfo (contiene un blocco di informazioni su ciascun processore) e/proc/meminfo (contiene una serie di statistiche generali sulla memoria, incluso MemTotal).

6

Su Windows è possibile utilizzare GlobalMemoryStatusEx per ottenere la quantità di RAM effettiva.

Le informazioni sul processore possono essere ottenute tramite GetSystemInfo.

5

Ecco un metodo per ottenere le informazioni desiderate su una macchina Windows. L'ho copiato e incollato da un progetto reale con alcune modifiche minori, quindi sentitevi liberi di ripulirlo per avere più senso.

 int CPUInfo[4] = {-1}; 
     unsigned nExIds, i = 0; 
     char CPUBrandString[0x40]; 
     // Get the information associated with each extended ID. 
     __cpuid(CPUInfo, 0x80000000); 
     nExIds = CPUInfo[0]; 
     for (i=0x80000000; i<=nExIds; ++i) 
     { 
      __cpuid(CPUInfo, i); 
      // Interpret CPU brand string 
      if (i == 0x80000002) 
       memcpy(CPUBrandString, CPUInfo, sizeof(CPUInfo)); 
      else if (i == 0x80000003) 
       memcpy(CPUBrandString + 16, CPUInfo, sizeof(CPUInfo)); 
      else if (i == 0x80000004) 
       memcpy(CPUBrandString + 32, CPUInfo, sizeof(CPUInfo)); 
     } 
     //string includes manufacturer, model and clockspeed 
     cout << "CPU Type: " << CPUBrandString << endl; 


     SYSTEM_INFO sysInfo; 
     GetSystemInfo(&sysInfo); 
     cout << "Number of Cores: " << sysInfo.dwNumberOfProcessors << endl; 

     MEMORYSTATUSEX statex; 
     statex.dwLength = sizeof (statex); 
     GlobalMemoryStatusEx(&statex); 
     cout << "Total System Memory: " << (statex.ullTotalPhys/1024)/1024 << "MB" << endl; 

Per ulteriori informazioni, vedere GetSystemInfo, GlobalMemoryStatusEx e __cpuid. Sebbene non l'avessi incluso, puoi anche determinare se il sistema operativo è a 32 o 64 bit tramite la funzione GetSystemInfo.

1

Su Solaris:

memoria -Per

prtconf | grep Memory 

-Per CPU

psrinfo -v | grep MHz 
3

Su Windows per determinare la velocità di clock della CPU:

double CPUSpeed() 
{ 
    wchar_t Buffer[_MAX_PATH]; 
    DWORD BufSize = _MAX_PATH; 
    DWORD dwMHz = _MAX_PATH; 
    HKEY hKey; 

    // open the key where the proc speed is hidden: 
    long lError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, 
           L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 
           0, 
           KEY_READ, 
           &hKey); 
    if(lError != ERROR_SUCCESS) 
    {// if the key is not found, tell the user why: 
     FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 
         NULL, 
         lError, 
         0, 
         Buffer, 
         _MAX_PATH, 
         0); 
     wprintf(Buffer); 
     return 0; 
    } 

    // query the key: 
    RegQueryValueEx(hKey, L"~MHz", NULL, NULL, (LPBYTE) &dwMHz, &BufSize); 
    return (double)dwMHz; 
} 
+0

@Anon Perché il downvote? –

0

Ho scritto un po 'di codice che utilizza il servizio WMI per ottenere la velocità massima con sveglia, so che è VB.net ma mostra l'idea:

''' <summary> 
''' Use WMI to get the Clock Speed in Hz 
''' </summary> 
Public Function GetMaxClockSpeedInHz() As Double 
    Dim manObj = New ManagementObject("Win32_Processor.DeviceID='CPU0'") 
    manObj.Get() 
    GetMaxClockSpeedInHz = Convert.ToInt32(manObj.Properties("MaxClockSpeed").Value) 
End Function 

Win32_OperatingSystem di riferimento: http://msdn.microsoft.com/en-us/library/Aa394239

Riferimento WMI: http://msdn.microsoft.com/en-us/library/aa394572(v=VS.85).aspx

0

L'OP desidera una velocità di clock della CPU che calcola la routine portatile tra Windows e Linux.Qui si va:

#ifdef WIN32 
#define WIN32_LEAN_AND_MEAN 
#include <windows.h> 
typedef unsigned __int64 usCount; 
static usCount GetUsCount() 
{ 
    static LARGE_INTEGER ticksPerSec; 
    static double scalefactor; 
    LARGE_INTEGER val; 
    if(!scalefactor) 
    { 
     if(QueryPerformanceFrequency(&ticksPerSec)) 
      scalefactor=ticksPerSec.QuadPart/1000000000000.0; 
     else 
      scalefactor=1; 
    } 
    if(!QueryPerformanceCounter(&val)) 
     return (usCount) GetTickCount() * 1000000000; 
    return (usCount) (val.QuadPart/scalefactor); 
} 
#else 
#include <sys/time.h> 
#include <time.h> 
#include <sched.h> 
typedef unsigned long long usCount; 
static usCount GetUsCount() 
{ 
#ifdef CLOCK_MONOTONIC 
    struct timespec ts; 
    clock_gettime(CLOCK_MONOTONIC, &ts); 
    return ((usCount) ts.tv_sec*1000000000000LL)+ts.tv_nsec*1000LL; 
#else 
    struct timeval tv; 
    gettimeofday(&tv, 0); 
    return ((usCount) tv.tv_sec*1000000000000LL)+tv.tv_usec*1000000LL; 
#endif 
} 
#endif 
static usCount usCountOverhead, CPUClockSpeed; 
#ifdef __GNUC__ 
#include "x86intrin.h" 
#define __rdtsc() __builtin_ia32_rdtsc() 
#endif 
static usCount GetClockSpeed() 
{ 
    int n; 
    usCount start, end, start_tsc, end_tsc; 
    if(!usCountOverhead) 
    { 
    usCount foo=0; 
    start=GetUsCount(); 
    for(n=0; n<1000000; n++) 
    { 
     foo+=GetUsCount(); 
    } 
    end=GetUsCount(); 
    usCountOverhead=(end-start)/n; 
    } 
    start=GetUsCount(); 
    start_tsc=__rdtsc(); 
    for(n=0; n<1000; n++) 
#ifdef WIN32 
    Sleep(0); 
#else 
    sched_yield(); 
#endif 
    end_tsc=__rdtsc(); 
    end=GetUsCount(); 
    return (usCount)((1000000000000.0*(end_tsc-start_tsc))/(end-start-usCountOverhead)); 
} 

Ovviamente questo funziona solo su x86/x64, e si basa su TSC contando alla stessa velocità della CPU. Se hai fatto cose strane di overclocking ad es. sul mio ho overcloccato l'FSB ma downrate il moltiplicatore per mantenere il core clock alle specifiche, quindi TSC conterà a FSB volte il moltiplicatore massimo che è troppo veloce.

Per ottenere i risultati migliori, prima di eseguire GetClockSpeed ​​(), suggerirei di eseguire un ciclo anti-SpeedStep, ad es.

usCount start; 
start=GetUsCount(); 
while(GetUsCount()-start<3000000000000ULL); 
CPUClockSpeed=GetClockSpeed(); 

Niall

Problemi correlati