Files
EgtGeneral/GetCpuInfo.cpp
DarioS 2042d2b4ee EgtGeneral 2.1b1 :
- aggiustate maiuscole/minuscole per inclusione file.
2022-02-26 18:04:08 +01:00

269 lines
8.3 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2015-2019
//----------------------------------------------------------------------------
// File : GetCpuInfo.cpp Data : 27.12.19 Versione : 2.2a1
// Contenuto : Funzioni per informazioni sulla CPU.
//
//
//
// Modifiche : 11.03.15 DS Creazione modulo.
// 27.12.19 DS Aggiunta lettura supporto AVX e AVX2.
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "/EgtDEv/Include/EGnPcInfo.h"
#include "/EgtDEv/Include/EGnStringUtils.h"
#include <intrin.h>
#define NOMINMAX
#include "Windows.h"
using namespace std ;
//------------------------------ Costanti ------------------------------------
// Bit indici estensioni della CPU
static const int BIT_MMX = 0x00800000 ;
static const int BIT_SSE = 0x02000000 ;
static const int BIT_SSE2 = 0x04000000 ;
static const int BIT_AVX = 0x20000000 ;
static const int BIT_AVX2 = 0x00000020 ;
static const int BIT_3DNOW = 0x80000000 ;
// lunghezza nomi
static const int VNAME_LEN = 3*sizeof(int) ;
//------------------------------ Strutture -------------------------------------
struct CpuInfo {
string sVendorName ; // nome del venditore
string sBrandName ; // brand
int nFamily ; // family of the processor
int nExtModel ; // extended model of processor
int nModel ; // model of processor
int nStepping ; // processor revision number
} ;
//------------------------------ Prototipi locali ------------------------------
static int ReadCpuInfo( CpuInfo& Info) ;
static bool OsSupport( int nExtra) ;
static string GetModelName( const char* szVendorName, int nFamily, int nExtModel, int nModel, int nStepping) ;
static string GetExtraString( int nExtra) ;
static int GetProcNbr( void) ;
//------------------------------------------------------------------------------
bool
GetCpuInfo( string& sCpuInfo)
{
// verifico validità stringa di ritorno
if ( &sCpuInfo == nullptr)
return false ;
// recupero informazioni sulla CPU
CpuInfo Info ;
int nExtra = ReadCpuInfo( Info) ;
// costruisco stringa per estensioni
string sExtra = GetExtraString( nExtra) ;
// recupero il numero di processori
int nProc = GetProcNbr() ;
sCpuInfo = "CPU " + Info.sBrandName ;
sCpuInfo += " - " + ToString( nProc) + " threads" ;
sCpuInfo += " - " + sExtra ;
return true ;
}
//------------------------------------------------------------------------------
// Ritorna nella struttura informazioni sulla CPU.
// Valore di ritorno 0 se impossibile usare CPUID, altrimenti extra abilitate.
//------------------------------------------------------------------------------
int
ReadCpuInfo( CpuInfo& Info)
{
int CPUInfo[4] ;
// lettura info base 0
CPUInfo[0] = 0 ;
__cpuid( CPUInfo, 0) ;
unsigned Ids = CPUInfo[0] ;
if ( Ids == 0)
return 0 ;
// nome del venditore
char CPUString[VNAME_LEN+1] ;
*((int*)CPUString) = CPUInfo[1] ;
*((int*)(CPUString+sizeof(int))) = CPUInfo[3] ;
*((int*)(CPUString+2*sizeof(int))) = CPUInfo[2] ;
CPUString[VNAME_LEN] = 0 ;
Info.sVendorName = CPUString ;
// lettura info base 1
__cpuid( CPUInfo, 1) ;
// stepping, model, family, extended model
Info.nStepping = CPUInfo[0] & 0xF ;
Info.nModel = ( CPUInfo[0] >> 4) & 0xF ;
Info.nFamily = ( CPUInfo[0] >> 8) & 0xF ;
Info.nExtModel = ( CPUInfo[0] >> 16) & 0xF ;
int nExtra = 0 ;
if ( ( CPUInfo[3] & BIT_MMX) && OsSupport( BIT_MMX))
nExtra |= BIT_MMX ;
if ( ( CPUInfo[3] & BIT_SSE) && OsSupport( BIT_SSE))
nExtra |= BIT_SSE ;
if ( (CPUInfo[3] & BIT_SSE2) && OsSupport( BIT_SSE2))
nExtra |= BIT_SSE2 ;
if ( (CPUInfo[2] & BIT_AVX))
nExtra |= BIT_AVX ;
// lettura info base 7
if ( Ids >= 7) {
__cpuid( CPUInfo, 7) ;
if ( (CPUInfo[1] & BIT_AVX2))
nExtra |= BIT_AVX2 ;
}
// lettura info estese 0
__cpuid( CPUInfo, 0x80000000) ;
unsigned nExIds = CPUInfo[0] ;
// lettura info estese 1
if ( nExIds >= 0x80000001) {
__cpuid( CPUInfo, 0x80000001) ;
if ( (CPUInfo[3] & BIT_3DNOW) && OsSupport( BIT_3DNOW))
nExtra |= BIT_3DNOW ;
}
// lettura info estese 2, 3 e 4
if ( nExIds >= 0x80000004) {
char CPUBrandString[4 * sizeof(CPUInfo)] ;
memset( CPUBrandString, 0, sizeof( CPUBrandString)) ;
__cpuid( CPUInfo, 0x80000002) ;
memcpy( CPUBrandString, CPUInfo, sizeof(CPUInfo)) ;
__cpuid( CPUInfo, 0x80000003) ;
memcpy( CPUBrandString + sizeof(CPUInfo), CPUInfo, sizeof(CPUInfo));
__cpuid( CPUInfo, 0x80000004) ;
memcpy( CPUBrandString + 2 * sizeof(CPUInfo), CPUInfo, sizeof(CPUInfo));
Info.sBrandName = CPUBrandString ;
Trim( Info.sBrandName) ;
}
else
// costruisco stringa per nome modello
Info.sBrandName = GetModelName( Info.sVendorName.c_str(),
Info.nFamily,
Info.nExtModel,
Info.nModel,
Info.nStepping) ;
return nExtra ;
}
//------------------------------------------------------------------------------
// Verifica se il sistema operativo supporta la prestazione extra passata.
//------------------------------------------------------------------------------
bool
OsSupport( int nExtra)
{
#ifndef _WIN64
try {
switch ( nExtra) {
case BIT_MMX :
__asm {
pxor mm0, mm0 // executing MMX instruction
emms
}
break ;
case BIT_SSE :
__asm {
xorps xmm0, xmm0 // executing SSE instruction
}
break ;
case BIT_SSE2 :
__asm {
xorpd xmm0, xmm0 // executing SSE2 instruction
}
break ;
case BIT_3DNOW :
__asm {
pfrcp mm0, mm0 // executing 3DNow! instruction
emms
}
break ;
}
}
//#pragma warning (suppress: 6320)
catch ( ...) {
return false ;
}
#endif
return true ;
}
//------------------------------------------------------------------------------
string
GetModelName( const char* szVendorName, int nFamily, int nExtModel, int nModel, int nStepping)
{
string sModelName ;
// se AMD
if ( strncmp( "AuthenticAMD", szVendorName, VNAME_LEN) == 0)
sModelName = "AMD " ;
// se Intel
else if ( strncmp( "GenuineIntel", szVendorName, VNAME_LEN) == 0)
sModelName = "INTEL " ;
// se Cyrix
else if ( strncmp( "CyrixInstead", szVendorName, VNAME_LEN) == 0)
sModelName = "Cyrix " ;
// se Centaur
else if ( strncmp( "CentaurHauls", szVendorName, VNAME_LEN) == 0)
sModelName = "Centaur " ;
// se Transmeta
else if ( strncmp( "TransmetaCPU", szVendorName, VNAME_LEN) == 0 ||
strncmp( "GenuineTMx86", szVendorName, VNAME_LEN) == 0)
sModelName = "Transmeta " ;
// se VIA
else if ( strncmp( "VIA VIA VIA ", szVendorName, VNAME_LEN) == 0)
sModelName = "VIA " ;
// altrimenti
else
sModelName = "Unknown " ;
// completo la stringa
sModelName += "(F" + ToString( nFamily) ;
sModelName += "E" + ToString( nExtModel) ;
sModelName += "M" + ToString( nModel) ;
sModelName += "S" + ToString( nStepping) + ")" ;
return sModelName ;
}
//------------------------------------------------------------------------------
string
GetExtraString( int nExtra)
{
string sExtra ;
if ( nExtra & BIT_MMX)
sExtra += "MMX+" ;
if ( nExtra & BIT_SSE)
sExtra += "SSE+" ;
if ( nExtra & BIT_SSE2)
sExtra += "SSE2+" ;
if ( nExtra & BIT_3DNOW)
sExtra += "3DNOW!+" ;
if ( nExtra & BIT_AVX)
sExtra += "AVX+" ;
if ( nExtra & BIT_AVX2)
sExtra += "AVX2+" ;
sExtra.pop_back() ;
return sExtra ;
}
//------------------------------------------------------------------------------
int
GetProcNbr( void)
{
SYSTEM_INFO sInfo ;
GetSystemInfo( &sInfo) ;
return sInfo.dwNumberOfProcessors ;
}