Windows环境下,获取CPU的制造商、CPU类型、CPU主频、内核个数、逻辑处理器个数


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

运行结果

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值