Количество процессоров не совпадает с CPUZ

Я хочу знать количество ядер процессора, поэтому я знаю этот код

SYSTEM_INFO siSysInfo;
DWORD getProcessorNum()
{
    GetSystemInfo(&siSysInfo);
    return siSysInfo.dwNumberOfProcessors;
}

Он возвращает 4. но когда я проверяю свой результат с помощью CPUZ, он возвращает 2Cores 4Thraeds

os Я пробую __cpuid с этим кодом

неподписанные регистры[4];

__cpuid(regs,4);
ядра = ((regs[0] >> 26) & 0x3f) + 1;

cout ‹‹ " ядер процессора: " ‹‹ ядер ‹‹ endl;

Он возвращает 8 ядер.

Не могли бы вы сказать мне, мой код неверен?

Я запускаю этот код с помощью MSVC++2010 на платформе Win7x64 с процессором i3.


person user1060028    schedule 25.11.2011    source источник
comment
CPUZ сообщает как об аппаратных ядрах, так и о логических ядрах. Похоже, на вашей машине включена технология Hyper-Threading, которая удвоит количество ядер (2 физических -> 4 логических).   -  person osgx    schedule 25.11.2011
comment
@osgx: не доверяйте этой странице, на ней много неточностей/непонятных утверждений. при использовании cpuid всегда доверяйте только счетчику, возвращенному из __cpuid(regs,0), и данным в руководствах для разработчиков Intel/AMD (отредактируйте: я вижу, что вы изменили комментарий/удалили его)   -  person Necrolis    schedule 25.11.2011
comment
Necrolis, можете ли вы сказать, почему процессор 4 вернул 8 ядер?   -  person osgx    schedule 25.11.2011
comment
@osgx: вы неправильно понимаете мой комментарий, он имел в виду ваш теперь удаленный раздел о том, что 4 является допустимым индексом процессора (__cpuid(regs,0) возвращает действительные индексы для использования с идентификатором процессора), что касается того, почему он получает 8, i3 имеет 4 потока исполнение, и его удваивает HT (как вы говорите).   -  person Necrolis    schedule 25.11.2011
comment
Но CPUz говорит: 2Cores 4Thraeds   -  person osgx    schedule 25.11.2011


Ответы (1)


проверить количество процессоров совсем не просто (в основном из-за многоядерных / сокетов / процессоров). Вызов GetSystemInfo возвращает количество потоков выполнения, которые видит система, CPUID имеет разные значения в зависимости от топологии процессора (см. руководства для разработчиков Intel).

Я построил кое-что, чтобы поймать все ситуации, вы можете найти это полезным:

static void GetProcessorTopology(size_t& nPhysical, size_t& nCores, size_t& nSystemThreads, size_t& nHWThreads, size_t& nThreadsPerCore)
{
    int nInfo[4];
    SYSTEM_INFO pSystemInfo;
    IsWOW64() ? GetNativeSystemInfo(&pSystemInfo) : GetSystemInfo(&pSystemInfo);
    nSystemThreads = pSystemInfo.dwNumberOfProcessors;
    if(TestTopologyLevel(nInfo,0x0,1) || TestTopologyLevel(nInfo,0x1,1))
    {
        nThreadsPerCore = nInfo[1] & 0xFFFF;
        if(TestTopologyLevel(nInfo,0x0,2) || TestTopologyLevel(nInfo,0x1,2))
        {
            nHWThreads = nInfo[1] & 0xFFFF;
            nCores = (nThreadsPerCore == 0) ? GetCoreCount(nInfo) : nHWThreads / nThreadsPerCore;
        }
        else
        {
            nHWThreads = nSystemThreads;
            nCores = GetCoreCount(nInfo);       
        }       
    }
    else
    {
        nThreadsPerCore = 1;
        nHWThreads = nSystemThreads;
        nCores = GetCoreCount(nInfo);
    }

    nPhysical = (nCores == 0) ? 1 : (nSystemThreads / nThreadsPerCore) / nCores;
}

static inline bool TestTopologyLevel(int* pInfo, int nMode, int nLevel)
{
    __cpuidex(pInfo,0xB,nMode);
    return ((pInfo[2] >> 8) & 0xFF) == nLevel;
}

static inline size_t GetCoreCount(int* nInfo)
{
    __cpuid(nInfo,0);
    if(nInfo[0] >= 4)
    {
        __cpuidex(nInfo,0x4,0x0);
        return (nInfo[0] >> 26) + 1;
    }
    else
    {
        __cpuid(nInfo,0x80000000);
        int nCPUID = nInfo[0];
        __cpuid(nInfo,1);                   
        if(nInfo[3] & 0x10000000 && nCPUID >= 0x80000008)
        {
            __cpuid(nInfo,0x80000008);
            return (nInfo[2] & 0xFF) + 1;
            }
        }

    return 1;
}
person Necrolis    schedule 25.11.2011