Ответ 1
В Windows вы можете использовать GlobalMemoryStatusEx, чтобы получить объем фактической ОЗУ.
Информация о процессоре может быть получена через GetSystemInfo.
Я работаю над комплектом профилирования кросс-платформы и хотел бы добавить информацию о процессоре машины (архитектура/тактовая частота/ядра) и ОЗУ (всего) к отчету каждого прогона. В настоящее время мне нужно настроить таргетинг на Windows и Unix, поэтому мне нужны методы для получения этой информации с обеих платформ, любые подсказки?
Изменить: Спасибо за отличные ответы. Теперь у меня есть архитектура процессора, количество ядер ядра и общая память, но мне все еще не хватает часов для процессора для каких-либо идей для этого?
В Windows вы можете использовать GlobalMemoryStatusEx, чтобы получить объем фактической ОЗУ.
Информация о процессоре может быть получена через GetSystemInfo.
Вот один из способов получения необходимой информации на машине Windows. Я скопировал и вложил его из реального проекта с некоторыми незначительными изменениями, поэтому не стесняйтесь очищать его, чтобы иметь больше смысла.
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;
Для получения дополнительной информации см. GetSystemInfo, GlobalMemoryStatusEx и __ cpuid. Хотя я не включил его, вы также можете определить, является ли ОС 32 или 64 бит через функцию GetSystemInfo.
Процессор прост. Используйте инструкцию cpuid
. Я оставлю другие плакаты, чтобы найти переносимый способ определения объема оперативной памяти в системе.: -)
Для специфичных для Linux методов вы можете получить доступ к /proc/meminfo
(и /proc/cpuinfo
, если вас не беспокоят, чтобы разобрать ответы cpuid
).
В Linux вы можете анализировать /proc/cpuinfo (содержит блок информации для каждого процессора) и /proc/meminfo (содержит множество общих статистических данных памяти, включая MemTotal).
В Windows для определения тактовой частоты процессора:
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;
}
В Solaris:
-Для памяти
prtconf | grep Memory
-For CPU
psrinfo -v | grep MHz
http://en.wikipedia.org/wiki/CPUID Может помочь CPUID
Я написал код, который использует WMI-сервис для получения Max Clock Speed, я знаю его VB.net, но он показывает идею:
''' <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: http://msdn.microsoft.com/en-us/library/Aa394239
Ссылка WMI: http://msdn.microsoft.com/en-us/library/aa394572(v=VS.85).aspx
OP хочет вычислить частоту тактовой частоты процессора, переносимую между Windows и Linux. Вот вы:
#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));
}
Очевидно, что это работает только на x86/x64, и он полагается на подсчет TSC с той же скоростью, что и процессор. Если вы сделали странные разгоны, например. на шахте я разгонял FSB, но уменьшал множитель, чтобы поддерживать часы ядра в спецификации, поэтому TSC будет считать в FSB время максимального множителя, который слишком быстр.
Чтобы получить наилучшие результаты, перед запуском GetClockSpeed () я предлагаю вам запустить цикл Anti-SpeedStep, например.
usCount start;
start=GetUsCount();
while(GetUsCount()-start<3000000000000ULL);
CPUClockSpeed=GetClockSpeed();
Найл
Для проектов Windows и Win32 С++:
В приведенном выше URL-адресе и содержащейся в нем статье представлены три разных способа получения информации о CPU в Windows. Исходный код находится в нижней части статьи, хорошо написан и имеет три полезных класса, которые вы можете вызывать из кода Win32 С++.