找回密码
 加入
搜索
查看: 5128|回复: 11

如何获取机器的CPU的物理个数

[复制链接]
发表于 2009-9-28 22:08:35 | 显示全部楼层 |阅读模式
请教各位,如何获取机器的CPU物理个数,最好是用WMI或API的方式。谢谢
发表于 2009-9-28 22:15:16 | 显示全部楼层
udf或者源码区去找
 楼主| 发表于 2009-9-28 22:20:45 | 显示全部楼层
2# netegg

找过很多,大部分是返回CPU的内核或超线程的数量,而不是实际的CPU个数。
发表于 2009-9-28 22:54:41 | 显示全部楼层
本帖最后由 netegg 于 2009-9-28 22:56 编辑

你指的数量是可见的物理个数?也就是多核cpu只认为是一个?
发表于 2009-9-29 06:20:58 | 显示全部楼层
不对,如果不是内核数的话,windows自己好像都没有,你看自带的设备管理器,双核cpu也是认定的两个
 楼主| 发表于 2009-9-30 09:00:33 | 显示全部楼层
你指的数量是可见的物理个数?也就是多核cpu只认为是一个?
netegg 发表于 2009-9-28 22:54


是的,就是您的意思.
 楼主| 发表于 2009-9-30 09:01:56 | 显示全部楼层
用erverest可以看出CPU的物理个数,确实不想只读出内核的个数.
发表于 2009-9-30 09:12:09 | 显示全部楼层
SetupDi*函数族应该可以判断出CPU的物理个数,但不会像everest那样读取准确。
http://msdn.microsoft.com/en-us/library/dd406734.aspx
 楼主| 发表于 2009-10-4 17:53:44 | 显示全部楼层
还没有搞定,还要寻求大家的帮助,顺祝大家十一假期快乐.
 楼主| 发表于 2009-12-15 17:49:28 | 显示全部楼层
#include <windows.h>
#include <malloc.h>    
#include <stdio.h>
#include <tchar.h>

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

int _cdecl _tmain ()
{
    LPFN_GLPI glpi;
    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 (1);
    }

    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\n"));
                    return (2);
                }
            } 
            else 
            {
                _tprintf(TEXT("\nError %d\n"), GetLastError());
                return (3);
            }
        } 
        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.
            numaNodeCount++;
            break;

        case RelationProcessorCore:
            processorCoreCount++;

            // A hyperthreaded core supplies more than one logical processor.
            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)
            {
                processorL1CacheCount++;
            }
            else if (Cache->Level == 2)
            {
                processorL2CacheCount++;
            }
            else if (Cache->Level == 3)
            {
                processorL3CacheCount++;
            }
            break;

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

        default:
            _tprintf(TEXT("\nError: Unsupported LOGICAL_PROCESSOR_RELATIONSHIP value.\n"));
            break;
        }
        byteOffset += sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
        ptr++;
    }

    _tprintf(TEXT("\nGetLogicalProcessorInformation results:\n"));
    _tprintf(TEXT("Number of NUMA nodes: %d\n"), 
             numaNodeCount);
    _tprintf(TEXT("Number of physical processor packages: %d\n"), 
             processorPackageCount);
    _tprintf(TEXT("Number of processor cores: %d\n"), 
             processorCoreCount);
    _tprintf(TEXT("Number of logical processors: %d\n"), 
             logicalProcessorCount);
    _tprintf(TEXT("Number of processor L1/L2/L3 caches: %d/%d/%d\n"), 
             processorL1CacheCount,
             processorL2CacheCount,
             processorL3CacheCount);
    
    free(buffer);

    return 0;
}
以代码为C++,我不懂,谁能帮忙转化为autoit的,或弄个UDF,谢谢。
发表于 2009-12-16 13:39:06 | 显示全部楼层
本帖最后由 netegg 于 2009-12-16 13:52 编辑

#include <WinAPI.au3>

$aSysInfo = _WinAPI_GetSystemInfo()

; GetProcessAffinityMask()
; http://msdn.microsoft.com/en-us/library/ms683213(VS.85).aspx
Global Const $PROCESS_ALL_ACCESS = 0x1F0FFF
$hProc = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS, False, @AutoItPID)
$aRet = _WinAPI_GetProcessAffinityMask($hProc)


MsgBox(0, "", "Physical processor count: " & @tab & $aSysInfo[5] & @LF & _     ;CPU物理数量
              "Logical processor count: " & @tab & (Log($aRet[2] + 1) / Log(2)) & @LF & _        ;CPU逻辑数量
              "Virtual processor count: " & @tab & (Log($aRet[2] + 1) / Log(2)) - $aSysInfo[5])   ;CPU虚拟数量

Func _WinAPI_GetSystemInfo($iInformation=-1)
    If $iInformation<>-1 And ($iInformation<1 Or $iInformation>10) Then Return SetError(1,0,-1)
    Local $aRet,$stSystemInfo=DllStructCreate("ushort;short;dword;ptr;ptr;dword;dword;dword;dword;short;short")

    $aRet=DllCall("kernel32.dll","none","GetSystemInfo","ptr",DllStructGetPtr($stSystemInfo))

    If @error Or Not IsArray($aRet) Then Return SetError(2,0,-1)

    If $iInformation<>-1 Then
        If $iInformation==1 Then Return DllStructGetData($stSystemInfo,1)
        Return DllStructGetData($stSystemInfo,$iInformation+1)
    EndIf
    Local $aSysInfo[10]
    $aSysInfo[0]=DllStructGetData($stSystemInfo,1)
    For $i=1 To 9
        $aSysInfo[$i]=DllStructGetData($stSystemInfo,$i+2)
    Next
    Return $aSysInfo
EndFunc
 楼主| 发表于 2009-12-16 17:33:53 | 显示全部楼层
谢谢,EGG。
这段脚本效果还是不太好,有的CPU还是不能实际检测。
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-9-22 15:31 , Processed in 0.093437 second(s), 24 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表