Как определить аппаратное обеспечение (процессор и оперативная память) на машине? - PullRequest
13 голосов
/ 12 мая 2009

Я работаю над кроссплатформенным набором профилирования и хотел бы добавить информацию о ЦП (архитектура / тактовая частота / ядра) и ОЗУ (всего) в отчет о каждом запуске. В настоящее время мне нужно ориентироваться на Windows и Unix, поэтому мне нужны методы для получения этой информации с обеих платформ, какие-либо подсказки?

Редактировать: Спасибо за отличные ответы. Теперь у меня есть архитектура процессора, количество процессоров и общее количество памяти, но мне все еще не хватает тактовой частоты для процессора. Есть идеи для этого?

Ответы [ 11 ]

8 голосов
/ 12 мая 2009

В Windows вы можете использовать GlobalMemoryStatusEx , чтобы получить объем фактической оперативной памяти.

Информация о процессоре может быть получена через GetSystemInfo .

6 голосов
/ 12 мая 2009

В 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;
}
5 голосов
/ 12 мая 2009

Вот один из способов получения необходимой информации на компьютере с 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.

4 голосов
/ 25 апреля 2018

Для Linux с GCC вы можете использовать очень похожее решение, например Windows. Вам нужно включить <cpuid.h>, и вам нужно изменить ввод для метода __cpuid() на основе this .

#include <cpuid.h>

char CPUBrandString[0x40];
unsigned int CPUInfo[4] = {0,0,0,0};

__cpuid(0x80000000, CPUInfo[0], CPUInfo[1], CPUInfo[2], CPUInfo[3]);
unsigned int nExIds = CPUInfo[0];

memset(CPUBrandString, 0, sizeof(CPUBrandString));

for (unsigned int i = 0x80000000; i <= nExIds; ++i)
{
    __cpuid(i, CPUInfo[0], CPUInfo[1], CPUInfo[2], CPUInfo[3]);

    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));
}

cout << "CPU Type: " << CPUBrandString << endl;
4 голосов
/ 12 мая 2009

Процессор прост. Используйте инструкцию cpuid. Я оставлю другие постеры, чтобы найти портативный способ определения объема оперативной памяти в системе. : -)

Для методов, специфичных для Linux, вы можете получить доступ к /proc/meminfo/proc/cpuinfo, если вам не нужно разбирать ответы cpuid).

3 голосов
/ 12 мая 2009

В Linux вы можете анализировать / proc / cpuinfo (содержит блок информации о каждом процессоре) и / proc / meminfo (содержит различные общие статистические данные о памяти, включая MemTotal).

1 голос
/ 18 марта 2012

ОП хочет, чтобы процедура вычисления тактовой частоты процессора переносилась между 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 ​​() я бы посоветовал вам запустить цикл анти-SpeedStep, например

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

Найл

1 голос
/ 12 мая 2009

http://en.wikipedia.org/wiki/CPUID Может помочь для CPUID

1 голос
/ 12 мая 2009

На Солярисе:

-Для памяти

 prtconf | grep Memory

- для процессора

 psrinfo -v | grep MHz
0 голосов
/ 24 января 2017

Для проектов Windows и Win32 C ++:

http://www.codeguru.com/cpp/w-p/system/hardwareinformation/article.php/c9087/Three-Ways-to-Retrieve-Processor-Information.htm

Приведенный выше URL и содержащаяся в нем статья демонстрируют 3 различных способа получения информации о процессоре в Windows. Исходный код находится внизу статьи, он хорошо написан и содержит три полезных класса, которые можно вызывать из кода Win32 C ++.

...