获取CPU信息

齐少86 2016-01-07 11:31:04
各位 我用GetSystemInfo这个函数获取CPU核数,
SYSTEM_INFO si;
GetSystemInfo(&si);
DWORD cpu_core_num = si.dwNumberOfProcessors;
在有些电脑上获取不准确,在设备管理器里面看见有多核处理器,但是获取的确实是1核,请问这个到底什么什么原因?
另外还有什么其他方法获取CPU核心数的,多谢各位!
...全文
530 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq179862309 2016-02-02
  • 打赏
  • 举报
回复
__asm { CPUID }
machealx 2016-02-01
  • 打赏
  • 举报
回复
读取注册表 HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor 下面的根数量就是CPU的数量 目录上的右边还有详细的CPU信息。
cde32 2016-01-28
  • 打赏
  • 举报
回复
这也可以!!!
苦逼码农 2016-01-27
  • 打赏
  • 举报
回复
引用 10 楼 zhuceccf 的回复:
[quote=引用 8 楼 u012879787 的回复:] wmi接口获取, 啥都可以搞定啊。
请问如何通过代码获取逻辑处理器数量[/quote] wmi接口有啊, 网上有个工具,搜wmi编程。
齐少86 2016-01-25
  • 打赏
  • 举报
回复
引用 7 楼 zhuceccf 的回复:
[quote=引用 楼主 zhuceccf 的回复:] 各位 我用GetSystemInfo这个函数获取CPU核数, SYSTEM_INFO si; GetSystemInfo(&si); DWORD cpu_core_num = si.dwNumberOfProcessors; 在有些电脑上获取不准确,在设备管理器里面看见有多核处理器,但是获取的确实是1核,请问这个到底什么什么原因? 另外还有什么其他方法获取CPU核心数的,多谢各位!
还有 我用命令行wmic 然后 cpu get *获得的NumberOfCores值为1 但是资源管理器里面显示处理器确是2个 这是什么原因 另外 GetSystemInfo(&si);获得的也是单核的 请各位大神解我疑惑!!多谢[/quote] 刚看到一个帖子 说资源管理器上面显示的只是逻辑处理器 实际上是一种超线程技术 让一个处理器通过技术手段模拟成两个处理器。不是说的对不对 那么怎么能通过代码获取逻辑处理器的数量呢???
齐少86 2016-01-25
  • 打赏
  • 举报
回复
引用 8 楼 u012879787 的回复:
wmi接口获取, 啥都可以搞定啊。
请问如何通过代码获取逻辑处理器数量
苦逼码农 2016-01-25
  • 打赏
  • 举报
回复
wmi接口获取, 啥都可以搞定啊。
齐少86 2016-01-25
  • 打赏
  • 举报
回复
引用 楼主 zhuceccf 的回复:
各位 我用GetSystemInfo这个函数获取CPU核数, SYSTEM_INFO si; GetSystemInfo(&si); DWORD cpu_core_num = si.dwNumberOfProcessors; 在有些电脑上获取不准确,在设备管理器里面看见有多核处理器,但是获取的确实是1核,请问这个到底什么什么原因? 另外还有什么其他方法获取CPU核心数的,多谢各位!
还有 我用命令行wmic 然后 cpu get *获得的NumberOfCores值为1 但是资源管理器里面显示处理器确是2个 这是什么原因 另外 GetSystemInfo(&si);获得的也是单核的 请各位大神解我疑惑!!多谢
  • 打赏
  • 举报
回复
用CPUID指令
赵4老师 2016-01-07
  • 打赏
  • 举报
回复
虚拟机吧
paschen 版主 2016-01-07
  • 打赏
  • 举报
回复
这样获取,结构体中processorCoreCount就是代表核心数

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

// Helper function to count set bits in the processor mask.
DWORD CountSetBits(ULONG_PTR bitMask)
{
    DWORD LSHIFT = sizeof(ULONG_PTR)*8 - 1;
    DWORD bitSetCount = 0;
    ULONG_PTR bitTest = (ULONG_PTR)1 << LSHIFT;    
    DWORD i;
    
    for (i = 0; i <= LSHIFT; ++i)
    {
        bitSetCount += ((bitMask & bitTest)?1:0);
        bitTest/=2;
    }

    return bitSetCount;
}

//cpu信息结构体
typedef struct _cpuinfo
{
	char CPUString[0x20];
	char CPUBrandString[0x40];
	DWORD logicalProcessorCount;
	DWORD numaNodeCount;
	DWORD processorCoreCount;
	DWORD processorL1CacheCount;
	DWORD processorL2CacheCount;
	DWORD processorL3CacheCount;
	DWORD processorPackageCount;
}cpuinfo;

//返回CPU信息结构体
cpuinfo GetCPUInfo()
{
    LPFN_GLPI glpi;
    BOOL done = FALSE;
    PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL;
    PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr = NULL;
    DWORD returnLength = 0;
	cpuinfo mycpu = {0,0,0,0,0,0,0};
    DWORD byteOffset = 0;
    PCACHE_DESCRIPTOR Cache;

	int CPUInfo[4] = {-1};
	__cpuid(CPUInfo, 0);
    memset(mycpu.CPUString, 0, sizeof(mycpu.CPUString));
    *((int*)mycpu.CPUString) = CPUInfo[1];
    *((int*)(mycpu.CPUString+4)) = CPUInfo[3];
    *((int*)(mycpu.CPUString+8)) = CPUInfo[2];

	char CPUBrandString[0x40];
	__cpuid(CPUInfo, 0x80000000);
	unsigned nExIds = CPUInfo[0];
    memset(CPUBrandString, 0, sizeof(CPUBrandString));
	for (unsigned 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));
    }
	//将去年开头空格的字符串复制进结构体
	bool spaceinfront = true;
	int num = 0;
	for(char *pch = CPUBrandString; *pch != '\0';pch++)
	{
		if(*pch == ' ' && spaceinfront)
			continue;
		else
		{
			spaceinfront = false;
			mycpu.CPUBrandString[num++] = *pch;
		}
	}
	mycpu.CPUBrandString[num] = '\0';

    glpi = (LPFN_GLPI) GetProcAddress(GetModuleHandle(TEXT("kernel32")),"GetLogicalProcessorInformation");
    //if (NULL == glpi) 
        //GetLogicalProcessorInformation is not supported.

    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)
                    //ErrorAllocation failure
            } 
            else
			{
                //Error: GetLastError()
			}
        } 
        else
        {
            done = TRUE;
        }
    }

    ptr = buffer;

    while (byteOffset + sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION) <= returnLength) 
    {
        switch (ptr->Relationship) 
        {
        case RelationNumaNode:
            // Non-NUMA systems report a single record of this type.
            mycpu.numaNodeCount++;
            break;

        case RelationProcessorCore:
            mycpu.processorCoreCount++;

            // A hyperthreaded core supplies more than one logical processor.
            mycpu.logicalProcessorCount += CountSetBits(ptr->ProcessorMask);
            break;

        case RelationCache:
            // Cache data is in ptr->Cache, one CACHE_DESCRIPTOR structure for each cache. 
            Cache = &ptr->Cache;
            if (Cache->Level == 1)
            {
                mycpu.processorL1CacheCount++;
            }
            else if (Cache->Level == 2)
            {
                mycpu.processorL2CacheCount++;
            }
            else if (Cache->Level == 3)
            {
                mycpu.processorL3CacheCount++;
            }
            break;

        case RelationProcessorPackage:
            // Logical processors share a physical package.
            mycpu.processorPackageCount++;
            break;

        default:
            //Error: Unsupported LOGICAL_PROCESSOR_RELATIONSHIP value.
            break;
        }
        byteOffset += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
        ptr++;
    }   

    free(buffer);

    return mycpu;
}
赵4老师 2016-01-07
  • 打赏
  • 举报
回复
引用 5 楼 zhuceccf 的回复:
[quote=引用 2 楼 zhao4zhong1 的回复:] 虚拟机吧
虚拟机用这个函数获取不到?[/quote] 我猜。 你实际在各种虚拟机环境(比如HyperV、VMWare、VirtualBox、……)下测试一下。
齐少86 2016-01-07
  • 打赏
  • 举报
回复
引用 2 楼 zhao4zhong1 的回复:
虚拟机吧
虚拟机用这个函数获取不到?

64,648

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧