#include <Windows.h>
#include <iostream>
#include <sysinfoapi.h>
#include <string>
#include <string.h>
#include <locale.h>
#include <tchar.h>
typedef BOOL(WINAPI* LPFN_GLPI)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD);
#ifdef _WIN64
// method 2: usde winapi, works for x86 and x64
#include <intrin.h>
void getCpuInfo()
{
int cpuInfo[4] = { -1 };
char cpu_manufacture[32] = { 0 };
char cpu_type[32] = { 0 };
char cpu_freq[32] = { 0 };
__cpuid(cpuInfo, 0x80000002);
memcpy(cpu_manufacture, cpuInfo, sizeof(cpuInfo));
__cpuid(cpuInfo, 0x80000003);
memcpy(cpu_type, cpuInfo, sizeof(cpuInfo));
__cpuid(cpuInfo, 0x80000004);
memcpy(cpu_freq, cpuInfo, sizeof(cpuInfo));
std::cout << "CPU manufacture: " << cpu_manufacture << std::endl;
std::cout << "CPU type: " << cpu_type << std::endl;
std::cout << "CPU main frequency: " << cpu_freq << std::endl;
}
#else
// mothed 1: this kind asm embedded in code only works in x86 build
// save 4 register variables
DWORD deax;
DWORD debx;
DWORD decx;
DWORD dedx;
// init cpu in assembly language
void initCpu(DWORD veax)
{
__asm
{
mov eax, veax
cpuid
mov deax, eax
mov debx, ebx
mov decx, ecx
mov dedx, edx
}
}
long getCpuFreq()
{
int start, over;
_asm
{
RDTSC
mov start, eax
}
Sleep(50);
_asm
{
RDTSC
mov over, eax
}
return (over - start) / 50000;
}
std::string getManufactureID()
{
char manuID[25];
memset(manuID, 0, sizeof(manuID));
initCpu(0);
memcpy(manuID + 0, &debx, 4); // copy to array
memcpy(manuID + 4, &dedx, 4);
memcpy(manuID + 8, &decx, 4);
return manuID;
}
std::string getCpuType()
{
const DWORD id = 0x80000002; // start 0x80000002 end to 0x80000004
char cpuType[49];
memset(cpuType, 0, sizeof(cpuType));
for (DWORD t = 0; t < 3; t++)
{
initCpu(id + t);
memcpy(cpuType + 16 * t + 0, &deax, 4);
memcpy(cpuType + 16 * t + 4, &debx, 4);
memcpy(cpuType + 16 * t + 8, &decx, 4);
memcpy(cpuType + 16 * t + 12, &dedx, 4);
}
return cpuType;
}
DWORD CountSetBits(ULONG_PTR bitMask)
{
DWORD LSHIF = sizeof(ULONG_PTR) * 8 - 1;
DWORD bitSetCount = 0;
ULONG_PTR bitTest = (ULONG_PTR)1 << LSHIF;
DWORD i;
for (i = 0; i <= LSHIF; ++i) {
bitSetCount += ((bitMask & bitTest) ? 1 : 0);
bitTest /= 2;
}
return bitSetCount;
}
std::string getCpuKernelAndLogic()
{
LPFN_GLPI glpi = NULL;
BOOL done = FALSE;
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL;
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr = NULL;
DWORD returnLength = 0;
DWORD logicalProcessorCount = 0;
DWORD numaNodeCount = 0;
DWORD processorCoreCount = 0;
DWORD processorL1CacheCount = 0;
DWORD processorL2CacheCount = 0;
DWORD processorL3CacheCount = 0;
DWORD processorPackageCount = 0;
DWORD byteOffset = 0;
PCACHE_DESCRIPTOR Cache;
glpi = (LPFN_GLPI)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "GetLogicalProcessorInformation");
if (NULL == glpi) {
//_tprintf(TEXT("\nGetLogicalProcessorInformation is not supported.\n"));
return FALSE;
}
while (!done) {
DWORD rc = glpi(buffer, &returnLength);
if (FALSE == rc) {
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
if (buffer)
free(buffer);
buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)malloc(returnLength);
if (NULL == buffer) {
//_tprintf(TEXT("\nError: Allocation failure"));
return FALSE;
}
}
else {
//_tprintf(TEXT("\nError: %d"), GetLastError());
return FALSE;
}
}
else {
done = TRUE;
}
}
ptr = buffer;
if (NULL == ptr)
return FALSE;
while (byteOffset + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= returnLength) {
switch (ptr->Relationship)
{
case RelationNumaNode:
numaNodeCount++;
break;
case RelationProcessorCore:
processorCoreCount++;
logicalProcessorCount += CountSetBits(ptr->ProcessorMask);
break;
case RelationCache:
Cache = &ptr->Cache;
if (Cache->Level == 1)
{
processorL1CacheCount++;
}
else if (Cache->Level == 2)
{
processorL2CacheCount++;
}
else if (Cache->Level == 3)
{
processorL3CacheCount++;
}
break;
case RelationProcessorPackage:
processorPackageCount++;
break;
default:
//_tprintf(TEXT("\nError: Unsupported LOGICAL_PROCESSOR_RELATIONSHIP value.\n"));
break;
}
byteOffset += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
ptr++;
}
//_tprintf(TEXT("\nGetLogicalProcessorInformation 的结果:\n"));
//_tprintf(TEXT("\tNUMA 节点数: %d\n"),
//numaNodeCount);
//_tprintf(TEXT("\t芯片个数: %d\n"),
//processorPackageCount);
//_tprintf(TEXT("\t芯片核心个数: %d\n"),
processorCoreCount);
//_tprintf(TEXT("\t芯片逻辑处理器个数: %d\n"),
//logicalProcessorCount);
//_tprintf(TEXT("\t芯片L1/L2/L3级缓存个数: %d/%d/%d\n"),
//processorL1CacheCount,
//processorL2CacheCount,
//processorL3CacheCount);
free(buffer);
//_tprintf(TEXT("----------------------------------------------------------------\n"));
std::string str;
str = ", " + std::to_string((long long)processorCoreCount) + "个核心 ," + std::to_string((long long)logicalProcessorCount) + "个逻辑处理器\n";
return str;
}
void getCpuInfo()
{
std::cout << "CPU 制造商: " << getManufactureID() << std::endl;
std::cout << "处理器 : " << getCpuType() << " , " << getCpuFreq() << " MHz" << getCpuKernelAndLogic() << std::endl;
}
#endif
int main()
{
setlocale(LC_ALL, "");
getCpuInfo();
return 0;
}
运行结果