📄 cpuinfo.cpp
字号:
DWORD dwEcx = 0;
DWORD dwEdx = 0;
__asm
{
mov eax, 2
CPUID
cmp al, 1
jne end_find_intel_cacheinfo
// if one iteration isn't enough, this code won't produce anything meaningful!
// this is from intel; look into changing it
mov dwEax, eax
mov dwEbx, ebx
mov dwEcx, ecx
mov dwEdx, edx
end_find_intel_cacheinfo:
}
m_cpuStats.setCacheEax(dwEax);
m_cpuStats.setCacheEbx(dwEbx);
m_cpuStats.setCacheEcx(dwEcx);
m_cpuStats.setCacheEdx(dwEdx);
if (m_fDebug) m_osDebugResults << "Intel Cache Info EAX: " << dwEax << endl;
if (m_fDebug) m_osDebugResults << "Intel Cache Info EBX: " << dwEbx << endl;
if (m_fDebug) m_osDebugResults << "Intel Cache Info ECX: " << dwEcx << endl;
if (m_fDebug) m_osDebugResults << "Intel Cache Info EDX: " << dwEdx << endl;
}
// this function is mostly ripped from intel's developer.intel.com webpage
// on the CPUID instruction
void CpuInfo::determineOldIntelName()
{
bool fIsCeleron;
bool fIsXeon;
struct brand_entry
{
long lBrandValue;
char* pszBrand;
};
struct brand_entry brand_table[BRANDTABLESIZE] =
{
1, "Genuine Intel Celeron(TM) processor",
2, "Genuine Intel Pentium(R) III processor",
3, "Genuine Intel Pentium(R) III Xeon(TM) processor",
8, "Genuine Intel Pentium(R) 4 processor"
};
/* we don't support old intel cpu's that don't know CPUID
if (m_cpuStats.getKnowsCpuId() == 0)
{
// 8086 - 80486
switch(m_cpuStats.getFamily())
{
case 3:
m_strCpuIdentification = "Intel386(TM) processor";
break;
case 4:
m_strCpuIdentification = "Intel486(TM) processor";
break;
default:
m_strCpuIdentification = "Unknown processor";
break;
} */
if (determineHighestCpuId() < NAMESTRING_FEATURE)
{
switch (m_cpuStats.getFamily())
{
case 4: // 486
switch(m_cpuStats.getModel())
{
case 0:
case 1:
m_cpuStats.setName("Intel486(TM) DX processor");
break;
case 2:
m_cpuStats.setName("Intel486(TM) SX processor");
break;
case 3:
m_cpuStats.setName("IntelDX2(TM) processor");
break;
case 4:
m_cpuStats.setName("Intel486(TM) processor");
break;
case 5:
m_cpuStats.setName("IntelSX2(TM) processor");
break;
case 7:
m_cpuStats.setName("Writeback Enhanced IntelDX2(TM) processor");
break;
case 8:
m_cpuStats.setName("IntelDX4(TM) processor");
break;
default:
m_cpuStats.setName("Intel 486 processor");
break;
}
break;
case 5: // pentium
m_cpuStats.setName("Intel Pentium(R) processor");
break;
case 6: // pentium II and family
switch (m_cpuStats.getModel())
{
case 1:
m_cpuStats.setName("Intel Pentium(R) Pro processor");
break;
case 3:
m_cpuStats.setName("Intel Pentium(R) II processor, model 3");
break;
case 5:
case 7:
fIsCeleron = false;
fIsXeon = false;
determineCeleronAndXeon(m_cpuStats.getCacheEax(), &fIsCeleron, &fIsXeon, true);
determineCeleronAndXeon(m_cpuStats.getCacheEbx(), &fIsCeleron, &fIsXeon);
determineCeleronAndXeon(m_cpuStats.getCacheEcx(), &fIsCeleron, &fIsXeon);
determineCeleronAndXeon(m_cpuStats.getCacheEdx(), &fIsCeleron, &fIsXeon);
if (fIsCeleron)
{
m_cpuStats.setName("Intel Celeron(TM) processor, model 5");
}
else
{
if (fIsXeon)
{
if (m_cpuStats.getModel() == 5)
{
m_cpuStats.setName("Intel Pentium(R) II Xeon(TM) processor");
}
else
{
m_cpuStats.setName("Intel Pentium(R) III Xeon(TM) processor");
}
}
else
{
if (m_cpuStats.getModel() == 5)
{
m_cpuStats.setName("Intel Pentium(R) II processor, model 5");
}
else
{
m_cpuStats.setName("Intel Pentium(R) III processor");
}
}
}
break;
case 6:
m_cpuStats.setName("Intel Celeron(TM) processor, model 6");
break;
case 8:
m_cpuStats.setName("Intel Pentium(R) III Coppermine processor");
break;
default:
{
int brand_index = 0;
while ((brand_index < BRANDTABLESIZE) &&
((m_cpuStats.getFeatureEbx() & 0xff) != brand_table[brand_index].lBrandValue))
{
brand_index++;
}
if (brand_index < BRANDTABLESIZE)
{
m_cpuStats.setName(brand_table[brand_index].pszBrand);
}
else
{
m_cpuStats.setName("Unknown Genuine Intel processor");
}
break;
}
}
}
if (m_cpuStats.getFeature(MMX_FLAG))
{
string strName = m_cpuStats.getName();
strName += " with MMX";
m_cpuStats.setName(strName);
}
}
if (m_fDebug) m_osDebugResults << "CPU Old Intel name: " << m_cpuStats.getName() << endl;
}
// this is ripped from intel, but put into function form. instead of testing for
// each register, we have a function to test a register's value.
// newer processors won't even use this.
void CpuInfo::determineCeleronAndXeon(DWORD dwRegisterCache, bool* pfIsCeleron, bool* pfIsXeon, bool fIsEax)
{
DWORD dwCacheTemp;
dwCacheTemp = dwRegisterCache & 0xFF000000;
if (dwCacheTemp == 0x40000000)
{
*pfIsCeleron = true;
}
if ((dwCacheTemp >= 0x44000000) && (dwCacheTemp <= 0x45000000))
{
*pfIsXeon = true;
}
dwCacheTemp = dwRegisterCache & 0xFF0000;
if (dwCacheTemp == 0x400000)
{
*pfIsCeleron = true;
}
if ((dwCacheTemp >= 0x440000) && (dwCacheTemp <= 0x450000))
{
*pfIsXeon = true;
}
dwCacheTemp = dwRegisterCache & 0xFF00;
if (dwCacheTemp == 0x4000)
{
*pfIsCeleron = true;
}
if ((dwCacheTemp >= 0x4400) && (dwCacheTemp <= 0x4500))
{
*pfIsXeon = true;
}
if (!fIsEax)
{
dwCacheTemp = dwRegisterCache & 0xFF; // possibly not needed for m_dwCacheEax
if (dwCacheTemp == 0x40000000)
{
*pfIsCeleron = true;
}
if ((dwCacheTemp >= 0x44000000) && (dwCacheTemp <= 0x45000000))
{
*pfIsXeon = true;
}
}
}
//------------------------------------------------------------
// This speed-determination algorithm was taken from
// Alexandre Cesari -- acesari@aclogic.com
//
DWORD CpuInfo::calculateCpuSpeed(void) const
{
DWORD dwStartTicks = 0;
DWORD dwEndTicks = 0;
DWORD dwTotalTicks = 0;
DWORD dwCpuSpeed = 0;
__int64 n64Frequency ;
__int64 n64Start;
__int64 n64Stop ;
if (QueryPerformanceFrequency((LARGE_INTEGER*)&n64Frequency))
{
QueryPerformanceCounter((LARGE_INTEGER*)&n64Start);
dwStartTicks = determineTimeStamp();
Sleep(300);
dwEndTicks = determineTimeStamp();
QueryPerformanceCounter((LARGE_INTEGER*)&n64Stop);
dwTotalTicks = dwEndTicks - dwStartTicks;
dwCpuSpeed = dwTotalTicks / ((1000000*(n64Stop-n64Start))/n64Frequency);
}
else
{
dwCpuSpeed = 0;
}
return (dwCpuSpeed);
}
// this function is ripped from amd
DWORD CpuInfo::calculateCpuSpeedMethod2(void) const
{
int nTimeStart = 0;
int nTimeStop = 0;
DWORD dwStartTicks = 0;
DWORD dwEndTicks = 0;
DWORD dwTotalTicks = 0;
DWORD dwCpuSpeed = 0;
nTimeStart = timeGetTime();
for(;;)
{
nTimeStop = timeGetTime();
if ((nTimeStop - nTimeStart) > 1)
{
dwStartTicks = determineTimeStamp();
break;
}
}
nTimeStart = nTimeStop;
for(;;)
{
nTimeStop = timeGetTime();
if ((nTimeStop - nTimeStart) > 500) // one-half second
{
dwEndTicks = determineTimeStamp();
break;
}
}
dwTotalTicks = dwEndTicks - dwStartTicks;
dwCpuSpeed = dwTotalTicks / 500000;
return (dwCpuSpeed);
}
// Not always accurate but order of magnitude faster
//
// Copyright (c) 2001 J. Michael McGarrah (mcgarrah@mcgarware.com)
//
DWORD CpuInfo::getCpuSpeedFromRegistry(void) const
{
HKEY hKey;
LONG result;
DWORD dwSpeed = 0;
DWORD dwType = 0;
DWORD dwSpeedSize;
// Get the processor speed from registry
result = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"Hardware\\Description\\System\\CentralProcessor\\0",
0,
KEY_QUERY_VALUE,
&hKey);
// Check if the function has succeeded.
if (result == ERROR_SUCCESS)
{
result = ::RegQueryValueEx (hKey, _T("~MHz"), NULL, NULL, (LPBYTE)&dwSpeed, &dwSpeedSize);
if (result == ERROR_SUCCESS) {
//----------------------------------------------------------
// this function was modified so that it doesn't actually
// modify the object in any way. it's more of a utility
// function like calculateCpuSpeed() and
// calculateCpuSpeedMethod2()
//
}
else
{
// explicity make the speed 0 just in case RegQueryValueEx puts a value in dwSpeed
dwSpeed = 0;
}
}
else
{
}
// Make sure to close the reg key
RegCloseKey (hKey);
return (dwSpeed);
}
// stolen from amd
DWORD CpuInfo::determineTimeStamp(void) const
{
DWORD dwTickVal;
__asm
{
_emit 0Fh
_emit 31h
mov dwTickVal, eax
}
return (dwTickVal);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -