Archives pour la catégorie Système

Récupérer le nombre de cœurs et d’autres informations de votre processeur

gulftowndie

Intro :

Il peut être utile de connaître le nombre de cœur de votre processeur afin d’optimiser vos applications utilisant des processus légers.

On peut obtenir aussi les information des caches associés au CPU.

Prérequis :

– Savoir lire du C++

Explications :

Voici le fichier d’en-tête CPUInfo.h :

#ifndef CPU_INFO_H
#define CPU_INFO_H

#include <Windows.h>
#include <iostream>

#include "Defines.h"
#include "Types.h"

typedef bool (WINAPI *LPFN_GLPI)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD);

class CPUInfo    
{
public:
    CPUInfo();
    virtual ~CPUInfo();
    
    bool Initialize();

    uint16 GetLogicalProcessorCount();
    uint16 GetPhysicalProcessorCount();

    uint16 GetSystemProcessorCount();

    uint16 GetL1CacheCount();
    uint16 GetL2CacheCount();
    uint16 GetL3CacheCount();

private:
    void ParseSystemProcessorCount();
    bool ParseProcessorData();
    uint32 CountBits(uint64 bitMask);

private:
    uint16 m_iPhysicalProcessorCount;
    uint16 m_iLogicalProcessorCount;
    uint16 m_iProcessorCoreCount;

    uint16 m_iProcessorL1CacheCount;
    uint16 m_iProcessorL2CacheCount;
    uint16 m_iProcessorL3CacheCount;

    size_t m_iProcessorL1CacheSize;
    size_t m_iProcessorL2CacheSize;
    size_t m_iProcessorL3CacheSize;
};

#endif

 

Voici le fichier source CPUInfo.cpp :

#include "CPUInfo.h"

CPUInfo::CPUInfo() :
m_iProcessorCoreCount(0),
m_iPhysicalProcessorCount(0),
m_iLogicalProcessorCount(0),
m_iProcessorL1CacheCount(0),
m_iProcessorL2CacheCount(0),
m_iProcessorL3CacheCount(0),
m_iProcessorL1CacheSize(0),
m_iProcessorL2CacheSize(0),
m_iProcessorL3CacheSize(0)
{
}

CPUInfo::~CPUInfo()
{
}

bool CPUInfo::Initialize()
{
    if (!ParseProcessorData())
    {
        return false;
    }

    ParseSystemProcessorCount();

    return true;
}

bool CPUInfo::ParseProcessorData()
{
    m_iLogicalProcessorCount = 0;
    m_iPhysicalProcessorCount = 0;

    LPFN_GLPI Glpi;

    Glpi = (LPFN_GLPI) GetProcAddress(GetModuleHandle(TEXT("kernel32")),
        "GetLogicalProcessorInformation");
    
    if (Glpi == nullptr)
    {
        /* La fonction qui permet d'obtenir les informations
           du CPU n'est pas supportée */
        return false;
    }

    bool bDone = false;

    PSYSTEM_LOGICAL_PROCESSOR_INFORMATION pBuffer = nullptr;
    DWORD iReturnLength = 0;

    while (!bDone)
    {
        bool bSucess = Glpi(pBuffer, &iReturnLength);

        if (!bSucess)
        {
            if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
            {
                if (pBuffer)
                {
                    free(pBuffer);
                }

                pBuffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION) malloc(iReturnLength);

                if (pBuffer == nullptr)
                {
                    // Echec de l'allocation
                    return false;
                }
            }
            else
            {
                // Erreur inconnu
                return false;
            }
        }
        else
        {
            bDone = true;
        }
    }

    DWORD iByteOffset = 0;
    PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr = pBuffer;
    PCACHE_DESCRIPTOR pCache = nullptr;

    while (iByteOffset + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= iReturnLength)
    {
        switch (ptr->Relationship)
        {
            case RelationProcessorCore:
                {
                    // Nombre de processeurs physiques
                    m_iPhysicalProcessorCount++;

                    // Nombre de processeurs logiques (ceux utilisable par le système)
                    m_iLogicalProcessorCount += CountBits(ptr->ProcessorMask);

                    break;
                }
            case RelationCache:
                {
                    pCache = &ptr->Cache;

                    if (pCache->Level == 1)
                    {
                        m_iProcessorL1CacheCount++;

                        m_iProcessorL1CacheSize = pCache->Size;
                    }
                    else if (pCache->Level == 2)
                    {
                        m_iProcessorL2CacheCount++;

                        m_iProcessorL2CacheSize = pCache->Size;
                    }
                    else if (pCache->Level == 3)
                    {
                        m_iProcessorL3CacheCount++;

                        m_iProcessorL3CacheSize = pCache->Size;
                    }

                    break;
                }
        }

        iByteOffset += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
        ptr++;
    }

    free (pBuffer);

    return true;
}

uint32 CPUInfo::CountBits(uint64 bitMask)
{
    DWORD c = 0;

    while (bitMask != 0)
    {
        c += (bitMask & 1L);
        bitMask >>= 1;
    }

    return c;
}

void CPUInfo::ParseSystemProcessorCount()
{
    SYSTEM_INFO si;
    GetSystemInfo(&si);

    m_iProcessorCoreCount = (uint16) si.dwNumberOfProcessors;
}

uint16 CPUInfo::GetSystemProcessorCount()
{
    return m_iProcessorCoreCount;
}

uint16 CPUInfo::GetPhysicalProcessorCount()
{
    return m_iPhysicalProcessorCount;
}

uint16 CPUInfo::GetLogicalProcessorCount()
{
    return m_iLogicalProcessorCount;
}

uint16 CPUInfo::GetL1CacheCount()
{
    return m_iProcessorL1CacheCount;
}

uint16 CPUInfo::GetL2CacheCount()
{
    return m_iProcessorL2CacheCount;
}

uint16 CPUInfo::GetL3CacheCount()
{
    return m_iProcessorL3CacheCount;
}

 

Résumé :

Nous avons présenter une méthode pour obtenir le nombre de cœur(s) de votre CPU.

Références :

– http://blogs.media-tips.com/bernard.opic/2007/09/03/compter-le-nombre-de-1-dans-la-forme-binaire-d-un-nombre/

– https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms683194%28v=vs.85%29.aspx

Créer une icône de barre des tâches pour votre programme

taskbar

Intro :

Au lieu de garder l’icône représentative par défaut de votre programme, vous pouvez la remplacer en mettant une image de votre choix. Cette dernière image devra être du format .ico.

Vous pouvez en trouver à travers le web.

Prérequis :

– Savoir lire du C++

– Savoir initialiser DirectX 10 à travers la classe System

Explications :

– Télécharger une icône. Par exemple : Icone.ico

– Créer un fichier « Res.rc »

ICON ICON "Icone.ico"

Mettez ces fichiers dans le dossier des fichiers de ressources :

ressource

 

Le compilateur de Visual Studio C++ reconnaîtra automatiquement l’icône à lier dans votre programme et la chargera au lancement de votre programme.

Résumé :

Nous avons présenté une méthode permettant de remplacer l’icône classique de votre programme.

Mettre en surbrillance l’icone de la barre des tâches

barre

Intro :

Parfois on a besoin de captiver l’attention du joueur lorsque l’application est minimisée, par exemple lorsque le joueur reçoit un message depuis la messagerie.

Pour cela l’icône dans la barre des tâches peut être mise en surbrillance lorsque l’application est minimisée.

Prérequis :

– Aucun

Explications :

void FlashWindow()
{   
    if (IsIconic(m_Hwnd))
    {
        DWORD now = timeGetTime();
        DWORD then = now;

        // C'est la fonction qui permet de mettre en surbrillance
        FlashWindow(m_Hwnd, true);
         
        while (true)
        {
            if (!IsIconic(m_Hwnd))
            {
                FlashWindow(m_Hwnd, false);
                break;
            }
            else
            {
                // On met en surbrillance l'icône périodiquement !
                now = timeGetTime();
                DWORD timeSpan = now > then ? (now - then) : (then - now);
                if (timeSpan > 1000)
                {
                    then = now;
                    FlashWindow(m_Hwnd, true);
                    break;
                }
            }
        }
    }
}

Résumé :

Nous avons appris comment mettre en surbrillance l’icône de votre application dans la barre des tâches.

Obtenir le taux d’occupation du CPU

cpu

Intro :

Dans cet article nous verrons comment obtenir le taux de consommation total du CPU de votre système et puis comment obtenir le taux de consommation du CPU du processus de votre application.

Pour info, j’ai déjà rédigé un article sur un sujet adjacent : les informations système.

Prérequis :

Savoir lire un peu du C++.

Explications :

Créez un fichier CPUTimer.h :

#ifndef CPU_TIMER_H
#define CPU_TIMER_H

#include <pdh.h>

#pragma comment(lib, "pdh.lib")

class CPUTimer
{
public:
    CPUTimer();

    virtual ~CPUTimer();

    void Initialize();
    void Frame();

    int GetCpuTotalPercentage();
    int GetCpuProcessPercentage();

private:

    /* Consommation CPU total du système */
    HQUERY m_queryHandle;
    HCOUNTER m_counterHandle;
    unsigned long m_lastSampleTime;
    double m_cpuTotalUsage;
    double m_cpuProcessUsage;

    /* Consommation CPU de l'application */
    ULARGE_INTEGER lastCPU, lastSysCPU, lastUserCPU;
    int numProcessors;
    HANDLE self;
};

#endif

 

On accède aux pourcentages de consommation du CPU par le biais des fonctions :

GetCpuTotalPercentage();
GetCpuProcessPercentage();

 

Créez un fichier CPUTimer.cpp :

#include "CPUTimer.h"

CPUTimer::CPUTimer()
{
}

CPUTimer::~CPUTimer()
{
    PdhCloseQuery(m_queryHandle);
}

void CPUTimer::Initialize()
{
    m_cpuTotalUsage = 0;
    m_cpuProcessUsage = 0;

    /* Consommation CPU total du système */

    PDH_STATUS status;

    status = PdhOpenQuery(NULL, NULL, &m_queryHandle);

    status = PdhAddEnglishCounter(m_queryHandle, TEXT("\\Processor(_Total)\\% processor time"), NULL, &m_counterHandle);

    /***************************************/

    /* Consommation CPU de l'application */

    SYSTEM_INFO sysInfo;
    FILETIME ftime, fsys, fuser;
    
    GetSystemInfo(&sysInfo);
    numProcessors = sysInfo.dwNumberOfProcessors;
    
    GetSystemTimeAsFileTime(&ftime);
    memcpy(&lastCPU, &ftime, sizeof(FILETIME));
    
    self = GetCurrentProcess();

    GetProcessTimes(self, &ftime, &ftime, &fsys, &fuser);

    memcpy(&lastSysCPU, &fsys, sizeof(FILETIME));
    memcpy(&lastUserCPU, &fuser, sizeof(FILETIME));

    m_lastSampleTime = GetTickCount();
}

void CPUTimer::Frame()
{
    // On met à jour les informations toutes les secondes
    if ((m_lastSampleTime + 1000) < GetTickCount())
    {    
        m_lastSampleTime = GetTickCount(); 

        /* Consommation CPU total du système */

        PDH_FMT_COUNTERVALUE value; 

        PdhCollectQueryData(m_queryHandle);
        
        PdhGetFormattedCounterValue(m_counterHandle, PDH_FMT_LONG, NULL, &value);

        m_cpuTotalUsage = value.longValue;

        /* Consommation CPU de l'application */

        FILETIME ftime, fsys, fuser;
        ULARGE_INTEGER now, sys, user;
        double percent;
    
        GetSystemTimeAsFileTime(&ftime);
        memcpy(&now, &ftime, sizeof(FILETIME));
    
        GetProcessTimes(self, &ftime, &ftime, &fsys, &fuser);

        memcpy(&sys, &fsys, sizeof(FILETIME));
        memcpy(&user, &fuser, sizeof(FILETIME));

        percent = (sys.QuadPart - lastSysCPU.QuadPart) +
            (user.QuadPart - lastUserCPU.QuadPart);

        percent /= (now.QuadPart - lastCPU.QuadPart);

        percent /= numProcessors;
        lastCPU = now;

        lastUserCPU = user;
        lastSysCPU = sys;

        m_cpuProcessUsage = percent * 100;
    }
}

int CPUTimer::GetCpuTotalPercentage()
{
    return m_cpuTotalUsage;
}

int CPUTimer::GetCpuProcessPercentage()
{
    return m_cpuProcessUsage;
}


Résumé :

Dans cet article nous avons appris comment obtenir le taux d’occupation du CPU de votre système mais aussi de votre application !

Récupérer les informations du système

Intro :

2000px-Computer-aj_aj_ashton_01.svg

Cette classe va vous permettre de récupérer les informations de votre système d’exploitation, du nom de votre processeur et de sa vitesse, du nombre de mémoire que vous disposez…


Explications :


std::string getOsName();
std::string getCpuName();
std::string getCpuSpeed();
std::string getTotalMemory();
std::string getAvailableMemory();

Dans le fichier ComputerInfo.h :

#ifndef COMPUTER_INFO_H
#define COMPUTER_INFO_H

class ComputerInfo
{
public:
    ComputerInfo();
    ~ComputerInfo();

    void parseOSName();
    void parseCPU();
    void parseMemory();
    void parseHDSpace();
    
    std::string getOsName();
    std::string getCpuName();
    std::string getCpuSpeed();
    std::string getTotalMemory();
    std::string getAvailableMemory();

private:
    std::string m_sOsName;
    std::string m_sCpuName;
    std::string m_sCpuSpeed;
    std::string m_sTotalMemory;
    std::string m_sAvailableMemory;
};

#endif

Dans votre fichier ComputerInfo.cpp :

#include <direct.h>
#include "ComputerInfo.h"

ComputerInfo::ComputerInfo()
{
    parseOSName();
    parseCPU();
    parseMemory();
}

ComputerInfo::~ComputerInfo()
{
}

std::string ComputerInfo::getOsName()
{
    return m_sOsName;
}

std::string ComputerInfo::getCpuName()
{
    return m_sCpuName;
}

std::string ComputerInfo::getCpuSpeed()
{
    return m_sCpuSpeed;
}

std::string ComputerInfo::getTotalMemory()
{
    return m_sTotalMemory;
}

std::string ComputerInfo::getAvailableMemory()
{
    return m_sAvailableMemory;
}

void ComputerInfo::parseOSName()
{
    OSVERSIONINFO osvi;
    ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    GetVersionEx(&osvi);

    std::string sOSName;

    switch(osvi.dwMajorVersion)
    {
        case 6:
            {
                if (osvi.dwMinorVersion == 3)
                    sOSName = "Windows 8.1";
                else if (osvi.dwMinorVersion == 2)
                    sOSName = "Windows 8";
                else if (osvi.dwMinorVersion == 1)
                    sOSName = "Windows 7";
                else if (osvi.dwMinorVersion == 0)
                    sOSName = "Windows Vista";
            }
            break;
        case 5:
            {
                if (osvi.dwMinorVersion == 1)
                    sOSName = "Windows XP";
            }
            break;

        default: sOSName = "OS Inconnu";
    }

    m_sOsName = sOSName;
}

void ComputerInfo::parseCPU()
{
    int CPUInfo[4] = {-1};
    unsigned   nExIds, i =  0;
    char CPUBrandString[0x40];

    __cpuid(CPUInfo, 0x80000000);
    nExIds = CPUInfo[0];
    for (i=0x80000000; i<=nExIds; ++i)
    {
        __cpuid(CPUInfo, i);

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

    m_sCpuName = CPUBrandString;

    /************************************/
    char Buffer[_MAX_PATH];
    DWORD BufSize = _MAX_PATH;
    DWORD dwMHz = _MAX_PATH;
    HKEY hKey;

    long lError = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
            "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
             0,
             KEY_READ,
             &hKey);
    
    if(lError != ERROR_SUCCESS)
    {
           FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
                         NULL,
                         lError,
                         0,
                         Buffer,
                         _MAX_PATH,
                         0);
    }

    RegQueryValueEx(hKey, "~MHz", NULL, NULL, (LPBYTE) &dwMHz,
                    &BufSize);

    char string[512] = { 0 };
    
    sprintf(string, "%i", dwMHz);

    m_sCpuSpeed = std::string(string) + " MHz";
}

void ComputerInfo::parseMemory()
{
    MEMORYSTATUSEX status;
    
    status.dwLength = sizeof(status);

    GlobalMemoryStatusEx(&status);

    int totalPhysicalMem = 0;
    int availableMem = 0;

    totalPhysicalMem = (int) status.ullTotalPhys / 1024;
    totalPhysicalMem = (totalPhysicalMem / 1024) + 1;

    availableMem = (int) status.ullAvailPhys / 1024;
    availableMem = (availableMem / 1024) + 1;

    m_sTotalMemory = MiscManager::intToString(totalPhysicalMem) +
                   " MB";
    m_sAvailableMemory = MiscManager::intToString(availableMem) +
                       " MB";
}


Résumé :

Cette classe permet d’accéder aux informations de votre système d’exploitation Windows.