views:

1043

answers:

7

I'm working on a cross platform profiling suite, and would like to add information about the machine's CPU (architecture/clock speed/cores) and RAM(total) to the report of each run. Currently I need to target Windows and Unix, so I need methods to obtain this information from both platforms, any clues?

Edit: Thanks for the great answers, Now I got CPU architecture, CPU number of cores and total Memory, but I'm still lacking a clockspeed for the CPU any ideas for that one?

+2  A: 

The CPU is easy. Use the cpuid instruction. I'll leave other posters to find a portable way to determine how much RAM a system has. :-)

For Linux-specific methods, you can access /proc/meminfo (and /proc/cpuinfo, if you can't be bothered to parse cpuid responses).

Chris Jester-Young
And presumably how to find CPU information on a processor that doesn't have any sort of CPUID instruction? ;)(Would CPUID even tell you how many cores the processor package had?)
araqnid
Read: http://www.intel.com/design/processor/applnots/241618.htm (short answer: yes). All bets are off if the CPU is too old to support cpuid, but no modern system has this issue.
Chris Jester-Young
I was thinking that not all systems are based on i386-architecture processors. (Although aware that this possibly wasn't a situation the OP was interested in)
araqnid
Bleh, all the world's an x86/x64! :-P (Just kidding.)
Chris Jester-Young
+1  A: 

On Linux you can parse /proc/cpuinfo (contains a block of info on each processor) and /proc/meminfo (contains a variety of general memory statistics, including MemTotal).

araqnid
+2  A: 

On Windows you can use GlobalMemoryStatusEx to get the amount of actual RAM.

Processor information can be obtained via GetSystemInfo.

jeffamaphone
+1  A: 

Here is one method for getting the information you want on a Windows machine. I copied and pasted it from an actual project with some minor modifications, so feel free to clean it up to make more sense.

        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;

For more information, see GetSystemInfo, GlobalMemoryStatusEx and __cpuid. Although I didn't include it, you can also determine if the OS is 32 or 64 bit via the GetSystemInfo function.

bsruth
+1  A: 

On Solaris:

-For memory

 prtconf | grep Memory

-For CPU

 psrinfo -v | grep MHz
Robert Gould
A: 

On Windows to determine CPU clock speed:

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;
}
Robert Gould
@Anon Why the downvote?
Robert Gould
+1  A: 

http://en.wikipedia.org/wiki/CPUID Might help for the CPUID

Sweeney