Jump to content
  • Advertisement
Sign in to follow this  
_the_phantom_

Obtaining system information

This topic is 3344 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Does anyone know of a lib or classes, C++ or .Net based, which would allow me to obtain various system information? Mostly I'm after processor type, speed, number of physics and logical cores active and what level of SSE support they have and optionally cache details, memory bus and speed. Idealy I also need something which will work on XP onwards if possible. Anyone got any ideas on how I would get such information, or of any libs which could help obtain it?

Share this post


Link to post
Share on other sites
Advertisement
From a chunk of my engine, will get CPU data (type, features, L1 & L2 cache size, number of processors, and the speed of each), physical RAM, and OS. Works on x64 and x86, but isn't widely tested:

static const unsigned PROCESSOR_UNKNOWN = 0;
static const unsigned PROCESSOR_AMD = 1;
static const unsigned PROCESSOR_INTEL = 2;

//============================================================================
// Error handler
//============================================================================
static void ErrorBox(const std::string& strError)
{
MessageBoxA(NULL, strError.c_str(), "Error", MB_ICONERROR);
}

//============================================================================
// Read the CPU speed from the registry
//============================================================================
static DWORD ReadCPUSpeedFromRegistry(DWORD dwCPU)
{
HKEY hKey;
DWORD dwSpeed;

// Get the key name
char szKey[256];
_snprintf(szKey, sizeof(szKey),
"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d\\", dwCPU);

// Open the key
if(RegOpenKeyExA(HKEY_LOCAL_MACHINE,szKey, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
{
return 0;
}

// Read the value
DWORD dwLen = 4;
if(RegQueryValueExA(hKey, "~MHz", NULL, NULL, (LPBYTE)&dwSpeed, &dwLen) != ERROR_SUCCESS)
{
RegCloseKey(hKey);
return 0;
}

// Cleanup and return
RegCloseKey(hKey);
return dwSpeed;
}

//============================================================================
// Calculate and log the CPU speed and features
//============================================================================
static void LogCPU()
{
unsigned nHighestFeature;
unsigned nHighestFeatureEx;
int nBuff[4];
char szMan[13];
char szFeatures[256];
unsigned nProcessorType;

// Get CPU manufacturer and highest CPUID
__cpuid(nBuff, 0);
nHighestFeature = (unsigned)nBuff[0];
*(int*)&szMan[0] = nBuff[1];
*(int*)&szMan[4] = nBuff[3];
*(int*)&szMan[8] = nBuff[2];
szMan[12] = 0;
if(strcmp(szMan, "AuthenticAMD") == 0)
nProcessorType = PROCESSOR_AMD;
else if(strcmp(szMan, "GenuineIntel") == 0)
nProcessorType = PROCESSOR_INTEL;
else
nProcessorType = PROCESSOR_UNKNOWN;

// Get highest extended feature
__cpuid(nBuff, 0x80000000);
nHighestFeatureEx = (unsigned)nBuff[0];

// Get processor brand name
if(nHighestFeatureEx >= 0x80000004)
{
char szCPUName[49];
szCPUName[0] = 0;
__cpuid((int*)&szCPUName[0], 0x80000002);
__cpuid((int*)&szCPUName[16], 0x80000003);
__cpuid((int*)&szCPUName[32], 0x80000004);
szCPUName[48] = 0;
for(int i=(int)strlen(szCPUName)-1; i>=0; --i)
{
if(szCPUName == ' ')
szCPUName = '\0';
else
break;
}

ELog::Get().SystemFormat("PERF : CPU: %s (%s)\n", szCPUName, szMan);
}
else
ELog::Get().SystemFormat("PERF : CPU: %s\n", szMan);

// Get CPU features
szFeatures[0] = 0;
if(nHighestFeature >= 1)
{
__cpuid(nBuff, 1);
if(nBuff[3] & 1<<0)
strcat(szFeatures, "FPU ");
if(nBuff[3] & 1<<23)
strcat(szFeatures, "MMX ");
if(nBuff[3] & 1<<25)
strcat(szFeatures, "SSE ");
if(nBuff[3] & 1<<26)
strcat(szFeatures, "SSE2 ");
if(nBuff[2] & 1<<0)
strcat(szFeatures, "SSE3 ");

// Intel specific:
if(nProcessorType == PROCESSOR_INTEL)
{
if(nBuff[2] & 1<<9)
strcat(szFeatures, "SSSE3 ");
if(nBuff[2] & 1<<7)
strcat(szFeatures, "EST ");
}

if(nBuff[3] & 1<<28)
strcat(szFeatures, "HTT ");
}

// AMD specific:
if(nProcessorType == PROCESSOR_AMD)
{
// Get extended features
__cpuid(nBuff, 0x80000000);
if(nHighestFeatureEx >= 0x80000001)
{
__cpuid(nBuff, 0x80000001);
if(nBuff[3] & 1<<31)
strcat(szFeatures, "3DNow! ");
if(nBuff[3] & 1<<30)
strcat(szFeatures, "Ex3DNow! ");
if(nBuff[3] & 1<<22)
strcat(szFeatures, "MmxExt ");
}

// Get level 1 cache size
if(nHighestFeatureEx >= 0x80000005)
{
__cpuid(nBuff, 0x80000005);
ELog::Get().SystemFormat("PERF : L1 cache size: %dK\n", ((unsigned)nBuff[2])>>24);
}
}

// Get cache size
if(nHighestFeatureEx >= 0x80000006)
{
__cpuid(nBuff, 0x80000006);
ELog::Get().SystemFormat("PERF : L2 cache size: %dK\n", ((unsigned)nBuff[2])>>16);
}

// Log features
ELog::Get().SystemFormat("PERF : CPU Features: %s\n", szFeatures);

// Get misc system info
SYSTEM_INFO theInfo;
GetSystemInfo(&theInfo);

// Log number of CPUs and speeds
ELog::Get().SystemFormat("PERF : Number of CPUs: %d\n", theInfo.dwNumberOfProcessors);
for(DWORD i=0; i<theInfo.dwNumberOfProcessors; ++i)
{
DWORD dwCPUSpeed = ReadCPUSpeedFromRegistry(i);
ELog::Get().SystemFormat("PERF : * CPU %d speed: ~%dMHz\n", i, dwCPUSpeed);
}
}

//============================================================================
// Calculate and log the amount of RAM in the machine
//============================================================================
static void LogRAM()
{
// Get memory status
MEMORYSTATUS theStatus;
ZeroMemory(&theStatus,sizeof(theStatus));
theStatus.dwLength = sizeof(theStatus);
GlobalMemoryStatus(&theStatus);

// Log it
DWORD dwRAM = (DWORD)(theStatus.dwTotalPhys/(1024*1024));
if(theStatus.dwTotalPhys != dwRAM*1024*1024)
++dwRAM;
ELog::Get().SystemFormat("PERF : Available physical RAM: %dMB/%dMB\n",
theStatus.dwAvailPhys/(1024*1024), dwRAM);
}

//============================================================================
// Determine OS type
//============================================================================
static void LogOS()
{
char szOS[256];
OSVERSIONINFOEXA osInfo;
SYSTEM_INFO sysInfo;

// Get system info
ZeroMemory(&sysInfo, sizeof(sysInfo));
GetSystemInfo(&sysInfo);

// Get OS version
strcpy(szOS, "PERF : OS: ");
ZeroMemory(&osInfo, sizeof(osInfo));
osInfo.dwOSVersionInfoSize = sizeof(osInfo);
if(!GetVersionExA((OSVERSIONINFOA*)&osInfo))
{
ZeroMemory(&osInfo, sizeof(osInfo));
osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
GetVersionExA((OSVERSIONINFOA*)&osInfo);
}

// Win 9x
if(osInfo.dwPlatformId == 1)
{
if((osInfo.dwMajorVersion == 4) && (osInfo.dwMinorVersion == 0))
strcat(szOS, "Windows 95 ");
else if((osInfo.dwMajorVersion == 4) && (osInfo.dwMinorVersion == 10))
strcat(szOS, "Windows 98 ");
else if((osInfo.dwMajorVersion == 4) && (osInfo.dwMinorVersion == 90))
strcat(szOS, "Windows ME ");
else
strcat(szOS, "Unknown Windows OS ");
}

// Win NT
else if(osInfo.dwPlatformId == 2)
{
if((osInfo.dwMajorVersion == 4) && (osInfo.dwMinorVersion == 0))
strcat(szOS, "Windows NT 4.0 ");
else if((osInfo.dwMajorVersion == 5) && (osInfo.dwMinorVersion == 0))
strcat(szOS, "Windows 2000 ");
else if((osInfo.dwMajorVersion == 5) && (osInfo.dwMinorVersion == 1))
strcat(szOS, "Windows XP ");
else if((osInfo.dwMajorVersion == 5) && (osInfo.dwMinorVersion == 2))
{
if(GetSystemMetrics(89)) // SM_SERVERR2 == 89
strcat(szOS, "Windows Server 2003 R2 ");
else if((osInfo.wProductType == VER_NT_WORKSTATION) &&
(sysInfo.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64))
{
strcat(szOS, "Windows XP Professional x64 Edition ");
}
else
strcat(szOS, "Windows Server 2003 ");
}
else if((osInfo.dwMajorVersion == 6) && (osInfo.dwMinorVersion == 0))
strcat(szOS, "Windows Vista ");
else
strcat(szOS, "Unknown WinNT OS ");
}

// Unknown
else
strcat(szOS, "Unknown Operating System ");

strcat(szOS, osInfo.szCSDVersion);
strcat(szOS, "\n");

// Log
ELog::Get().SystemLog(szOS);
#if defined(BUILD_X64)
ELog::Get().SystemLog("PERF : Win64 version\n");
#elif defined(_WIN32)
ELog::Get().SystemLog("PERF : Win32 version\n");
#else
ELog::Get().SystemLog("PERF : Unknown version\n");
#endif
}

Share this post


Link to post
Share on other sites
Cheers for the info guys; I did know about __cpuid however that was looking like going into a murky world of familys, models and all manner of sillyness just to figure out what type of processor I was on.

Cheers for the code EvilSteve; makes me wonder why I didn't think about poking around in the registry before now myself [oh]

Share this post


Link to post
Share on other sites
Quote:
Original post by phantom
makes me wonder why I didn't think about poking around in the registry before now myself [oh]

Because then you'd be using undocumented information (I'm pretty sure) that may change form, disappear, or be a lie because so many apps break when any of the former happen. And then people blame Microsoft of course.

Share this post


Link to post
Share on other sites
Well, it doesn't need long term maintainance, just needs to work long enough for me to gain information from people for data generation thus pulling a few details from the registry, maybe with the __cpuid carried along as well.

Share this post


Link to post
Share on other sites
Evil, this is probably going to seem like a retarded question so excuse me as I am new to this, but when I attempt to run this in Visual Studio 2008 I get errors relating to ELog based lines, presumably because I haven't included it for it to be able to call the functions included in it, can I just replace these lines with a standard output stream?

Nevermind, I tried using a standard output stream and it didn't work, so I guess my question is: Is there a way to output this information if I am running it as a win32 console application through Visual Studio 2008.

[Edited by - Spacemonkey49 on October 15, 2009 12:30:47 PM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!