Reliable way to programmatically get the number of hardware threads on Windows










8















I'm struggling to find a reliable way to get the number of hardware threads on Windows. I am running a Windows 7 Professional SP1 64-bit on a machine with dual CPU Intel Xeon E5-2699 v3 @ 2.30GHz totalizing 36 cores and 72 threads.
I have tried different methods to get the number of cores, and I have found that only two of them seem to work accurately in a 32-bit or 64-bit process. Here are my results:




+------------------------------------------------+----------------+----------------+
| Methods | 32-bit process | 64-bit process |
+------------------------------------------------+----------------+----------------+
| GetSystemInfo->dwNumberOfProcessors | 32 | 36 |
| GetNativeSystemInfo->dwNumberOfProcessors | 36 | 36 |
| GetLogicalProcessorInformation | 36 | 36 |
| GetProcessAffinityMask.processAffinityMask | 32 | 32 |
| GetProcessAffinityMask.systemAffinityMask | 32 | 32 |
| omp_get_num_procs | 32 | 36 |
| getenv("NUMBER_OF_PROCESSORS") | 36 | 36 |
| GetActiveProcessorCount(ALL_PROCESSOR_GROUPS) | 64 | 72 |
| GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS) | 64 | 72 |
| boost::thread::hardware_concurrency() | 32 | 36 |
| Performance counter API | 36 | 36 |
| WMI | 72 | 72 |
| HARDWAREDESCRIPTIONSystemCentralProcessor | 72 | 72 |
+------------------------------------------------+----------------+----------------+


I do not explain why all these functions return different values. The only 2 methods which seem reliable to me is either using WMI (but fairly complicated) or simply to read in the Windows registry the following key: HARDWAREDESCRIPTIONSystemCentralProcessor.



What do you think?
Do you confirm that the WMI and registry key methods are the only reliable methods?



Thanks in advance










share|improve this question
























  • You get however many you can effectively use in your program. Sure, WMI is never the wrong way to do this.

    – Hans Passant
    Jul 3 '15 at 14:37















8















I'm struggling to find a reliable way to get the number of hardware threads on Windows. I am running a Windows 7 Professional SP1 64-bit on a machine with dual CPU Intel Xeon E5-2699 v3 @ 2.30GHz totalizing 36 cores and 72 threads.
I have tried different methods to get the number of cores, and I have found that only two of them seem to work accurately in a 32-bit or 64-bit process. Here are my results:




+------------------------------------------------+----------------+----------------+
| Methods | 32-bit process | 64-bit process |
+------------------------------------------------+----------------+----------------+
| GetSystemInfo->dwNumberOfProcessors | 32 | 36 |
| GetNativeSystemInfo->dwNumberOfProcessors | 36 | 36 |
| GetLogicalProcessorInformation | 36 | 36 |
| GetProcessAffinityMask.processAffinityMask | 32 | 32 |
| GetProcessAffinityMask.systemAffinityMask | 32 | 32 |
| omp_get_num_procs | 32 | 36 |
| getenv("NUMBER_OF_PROCESSORS") | 36 | 36 |
| GetActiveProcessorCount(ALL_PROCESSOR_GROUPS) | 64 | 72 |
| GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS) | 64 | 72 |
| boost::thread::hardware_concurrency() | 32 | 36 |
| Performance counter API | 36 | 36 |
| WMI | 72 | 72 |
| HARDWAREDESCRIPTIONSystemCentralProcessor | 72 | 72 |
+------------------------------------------------+----------------+----------------+


I do not explain why all these functions return different values. The only 2 methods which seem reliable to me is either using WMI (but fairly complicated) or simply to read in the Windows registry the following key: HARDWAREDESCRIPTIONSystemCentralProcessor.



What do you think?
Do you confirm that the WMI and registry key methods are the only reliable methods?



Thanks in advance










share|improve this question
























  • You get however many you can effectively use in your program. Sure, WMI is never the wrong way to do this.

    – Hans Passant
    Jul 3 '15 at 14:37













8












8








8


2






I'm struggling to find a reliable way to get the number of hardware threads on Windows. I am running a Windows 7 Professional SP1 64-bit on a machine with dual CPU Intel Xeon E5-2699 v3 @ 2.30GHz totalizing 36 cores and 72 threads.
I have tried different methods to get the number of cores, and I have found that only two of them seem to work accurately in a 32-bit or 64-bit process. Here are my results:




+------------------------------------------------+----------------+----------------+
| Methods | 32-bit process | 64-bit process |
+------------------------------------------------+----------------+----------------+
| GetSystemInfo->dwNumberOfProcessors | 32 | 36 |
| GetNativeSystemInfo->dwNumberOfProcessors | 36 | 36 |
| GetLogicalProcessorInformation | 36 | 36 |
| GetProcessAffinityMask.processAffinityMask | 32 | 32 |
| GetProcessAffinityMask.systemAffinityMask | 32 | 32 |
| omp_get_num_procs | 32 | 36 |
| getenv("NUMBER_OF_PROCESSORS") | 36 | 36 |
| GetActiveProcessorCount(ALL_PROCESSOR_GROUPS) | 64 | 72 |
| GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS) | 64 | 72 |
| boost::thread::hardware_concurrency() | 32 | 36 |
| Performance counter API | 36 | 36 |
| WMI | 72 | 72 |
| HARDWAREDESCRIPTIONSystemCentralProcessor | 72 | 72 |
+------------------------------------------------+----------------+----------------+


I do not explain why all these functions return different values. The only 2 methods which seem reliable to me is either using WMI (but fairly complicated) or simply to read in the Windows registry the following key: HARDWAREDESCRIPTIONSystemCentralProcessor.



What do you think?
Do you confirm that the WMI and registry key methods are the only reliable methods?



Thanks in advance










share|improve this question
















I'm struggling to find a reliable way to get the number of hardware threads on Windows. I am running a Windows 7 Professional SP1 64-bit on a machine with dual CPU Intel Xeon E5-2699 v3 @ 2.30GHz totalizing 36 cores and 72 threads.
I have tried different methods to get the number of cores, and I have found that only two of them seem to work accurately in a 32-bit or 64-bit process. Here are my results:




+------------------------------------------------+----------------+----------------+
| Methods | 32-bit process | 64-bit process |
+------------------------------------------------+----------------+----------------+
| GetSystemInfo->dwNumberOfProcessors | 32 | 36 |
| GetNativeSystemInfo->dwNumberOfProcessors | 36 | 36 |
| GetLogicalProcessorInformation | 36 | 36 |
| GetProcessAffinityMask.processAffinityMask | 32 | 32 |
| GetProcessAffinityMask.systemAffinityMask | 32 | 32 |
| omp_get_num_procs | 32 | 36 |
| getenv("NUMBER_OF_PROCESSORS") | 36 | 36 |
| GetActiveProcessorCount(ALL_PROCESSOR_GROUPS) | 64 | 72 |
| GetMaximumProcessorCount(ALL_PROCESSOR_GROUPS) | 64 | 72 |
| boost::thread::hardware_concurrency() | 32 | 36 |
| Performance counter API | 36 | 36 |
| WMI | 72 | 72 |
| HARDWAREDESCRIPTIONSystemCentralProcessor | 72 | 72 |
+------------------------------------------------+----------------+----------------+


I do not explain why all these functions return different values. The only 2 methods which seem reliable to me is either using WMI (but fairly complicated) or simply to read in the Windows registry the following key: HARDWAREDESCRIPTIONSystemCentralProcessor.



What do you think?
Do you confirm that the WMI and registry key methods are the only reliable methods?



Thanks in advance







c++ windows multithreading winapi






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 13 '18 at 18:03









Arnaud

2,28122751




2,28122751










asked Jul 3 '15 at 14:33









benben

411




411












  • You get however many you can effectively use in your program. Sure, WMI is never the wrong way to do this.

    – Hans Passant
    Jul 3 '15 at 14:37

















  • You get however many you can effectively use in your program. Sure, WMI is never the wrong way to do this.

    – Hans Passant
    Jul 3 '15 at 14:37
















You get however many you can effectively use in your program. Sure, WMI is never the wrong way to do this.

– Hans Passant
Jul 3 '15 at 14:37





You get however many you can effectively use in your program. Sure, WMI is never the wrong way to do this.

– Hans Passant
Jul 3 '15 at 14:37












3 Answers
3






active

oldest

votes


















8














The API function that you need is GetLogicalProcessorInformationEx. Since you have more than 64 processors, your processors are grouped. GetLogicalProcessorInformation only reports the processors in the processor group that the thread is currently assigned. You need to use GetLogicalProcessorInformationEx to get past that limitation.



The documentation says:




On systems with more than 64 logical processors, the GetLogicalProcessorInformation function retrieves logical processor information about processors in the processor group to which the calling thread is currently assigned. Use the GetLogicalProcessorInformationEx function to retrieve information about processors in all processor groups on the system.







share|improve this answer






























    0














    You can use the CPUID instruction to query the processor directly (platform independent, though since you can't do inline asm in MSVC anymore for some compilers you'll need to use different functions to have access to it). The only downside is that as of a few years ago Intel and AMD handle this instruction differently, and you'll need to do a lot of work to ensure you are reading the information correctly. In fact, not only will you be able to get a core count, but you can get all kinds of processor topology information. Not sure how it works in a VM though if you are using that environment.






    share|improve this answer























    • CPUID is hardly platform independent. You yourself note that it doesn't always behave right, and you completely ignore other processors like ARM.

      – Raymond Chen
      Jul 3 '15 at 18:51


















    0














    Late answer with code:



    size_t myHardwareConcurrency()
    size_t concurrency=0;
    DWORD length=0;
    if(GetLogicalProcessorInformationEx(RelationAll,nullptr,&length)!=FALSE)
    return concurrency;
    if(GetLastError()!=ERROR_INSUFFICIENT_BUFFER)
    return concurrency;
    std::unique_ptr<void,void(*)(void*)>buffer(std::malloc(length),std::free);
    if(!buffer)
    return concurrency;
    unsigned char*mem=reinterpret_cast<unsigned char*>(buffer.get());
    if(GetLogicalProcessorInformationEx(RelationAll,reinterpret_cast<PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX>(mem),&length)==false)
    return concurrency;
    for(DWORD i=0;i<length;)
    auto*proc=reinterpret_cast<PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX>(mem+i);
    if(proc->Relationship==RelationProcessorCore)
    for(WORD group=0;group<proc->Processor.GroupCount;++group)
    for(KAFFINITY mask=proc->Processor.GroupMask[group].Mask;mask!=0;mask>>=1)
    concurrency+=mask&1;
    i+=proc->Size;
    return concurrency;


    It worked on my dual Xeon gold 6154 with Windows 64 bit system (2 procs * 18 cores/proc * 2 threads/core = 72 threads). The result is 72 both for 32 bit processes and for 64 bit processes.



    I do not have access to a system with a 32 bit Windows though.



    In case of error, it returns zero like std::thread::hardware_concurrency does.






    share|improve this answer

























    • According to MSDN you would just need to count the number of occurrences of RelationProcessorCore so the counting loop can be simplified to: if (proc->Relationship==RelationProcessorCore) ++concurrency;. This is because the number of groups a core belongs to is always 1 and the mask only contains a single bit denoting the position (or affinity) in that group. I guess it would also make counting under WoW64 emulation more robust...

      – klaus triendl
      Nov 13 '18 at 16:46












    • @klaustriendl I just edited the OP question to make a clear distinction between number of cores and number of threads. Although he used the word cores all along, the number he gave were for the number of hardware threads. Your suggestion would be correct to get the number of core, but the OP wanted the number of threads.

      – Arnaud
      Nov 13 '18 at 18:05











    • Thx @Arnaud Still you wouldn't have to loop through the groups as the group count is always 1. Anyway, to me the "number of active processor cores" was equivalent to the "number of logical processors", but reading further on PROCESSOR_RELATIONSHIP I understand that a core can have more than 1 logical processor. What happens under Wow64? Is the mask for logical processors 32 through 63 correct? Because the remarks state that it's incorrectly represented as duplicates for 0-31... (I guess for your specific machine these would be logical processors 32-35 of cores number 17+18?

      – klaus triendl
      Nov 13 '18 at 19:14











    • @klaustriendl On my machine (6 cores 12 threads 3930K), in x64 mode proc->Processor.GroupMask[0].Mask is 3 and I need to add 2 for each RelationProcessorCore

      – Arnaud
      Nov 13 '18 at 21:45











    • What do you mean exactly by x64 mode? Is it the 32-bit executable on a 64-bit OS, i.e. WoW64?

      – klaus triendl
      Nov 14 '18 at 8:35










    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f31209256%2freliable-way-to-programmatically-get-the-number-of-hardware-threads-on-windows%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    8














    The API function that you need is GetLogicalProcessorInformationEx. Since you have more than 64 processors, your processors are grouped. GetLogicalProcessorInformation only reports the processors in the processor group that the thread is currently assigned. You need to use GetLogicalProcessorInformationEx to get past that limitation.



    The documentation says:




    On systems with more than 64 logical processors, the GetLogicalProcessorInformation function retrieves logical processor information about processors in the processor group to which the calling thread is currently assigned. Use the GetLogicalProcessorInformationEx function to retrieve information about processors in all processor groups on the system.







    share|improve this answer



























      8














      The API function that you need is GetLogicalProcessorInformationEx. Since you have more than 64 processors, your processors are grouped. GetLogicalProcessorInformation only reports the processors in the processor group that the thread is currently assigned. You need to use GetLogicalProcessorInformationEx to get past that limitation.



      The documentation says:




      On systems with more than 64 logical processors, the GetLogicalProcessorInformation function retrieves logical processor information about processors in the processor group to which the calling thread is currently assigned. Use the GetLogicalProcessorInformationEx function to retrieve information about processors in all processor groups on the system.







      share|improve this answer

























        8












        8








        8







        The API function that you need is GetLogicalProcessorInformationEx. Since you have more than 64 processors, your processors are grouped. GetLogicalProcessorInformation only reports the processors in the processor group that the thread is currently assigned. You need to use GetLogicalProcessorInformationEx to get past that limitation.



        The documentation says:




        On systems with more than 64 logical processors, the GetLogicalProcessorInformation function retrieves logical processor information about processors in the processor group to which the calling thread is currently assigned. Use the GetLogicalProcessorInformationEx function to retrieve information about processors in all processor groups on the system.







        share|improve this answer













        The API function that you need is GetLogicalProcessorInformationEx. Since you have more than 64 processors, your processors are grouped. GetLogicalProcessorInformation only reports the processors in the processor group that the thread is currently assigned. You need to use GetLogicalProcessorInformationEx to get past that limitation.



        The documentation says:




        On systems with more than 64 logical processors, the GetLogicalProcessorInformation function retrieves logical processor information about processors in the processor group to which the calling thread is currently assigned. Use the GetLogicalProcessorInformationEx function to retrieve information about processors in all processor groups on the system.








        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Jul 3 '15 at 14:38









        David HeffernanDavid Heffernan

        519k348221214




        519k348221214























            0














            You can use the CPUID instruction to query the processor directly (platform independent, though since you can't do inline asm in MSVC anymore for some compilers you'll need to use different functions to have access to it). The only downside is that as of a few years ago Intel and AMD handle this instruction differently, and you'll need to do a lot of work to ensure you are reading the information correctly. In fact, not only will you be able to get a core count, but you can get all kinds of processor topology information. Not sure how it works in a VM though if you are using that environment.






            share|improve this answer























            • CPUID is hardly platform independent. You yourself note that it doesn't always behave right, and you completely ignore other processors like ARM.

              – Raymond Chen
              Jul 3 '15 at 18:51















            0














            You can use the CPUID instruction to query the processor directly (platform independent, though since you can't do inline asm in MSVC anymore for some compilers you'll need to use different functions to have access to it). The only downside is that as of a few years ago Intel and AMD handle this instruction differently, and you'll need to do a lot of work to ensure you are reading the information correctly. In fact, not only will you be able to get a core count, but you can get all kinds of processor topology information. Not sure how it works in a VM though if you are using that environment.






            share|improve this answer























            • CPUID is hardly platform independent. You yourself note that it doesn't always behave right, and you completely ignore other processors like ARM.

              – Raymond Chen
              Jul 3 '15 at 18:51













            0












            0








            0







            You can use the CPUID instruction to query the processor directly (platform independent, though since you can't do inline asm in MSVC anymore for some compilers you'll need to use different functions to have access to it). The only downside is that as of a few years ago Intel and AMD handle this instruction differently, and you'll need to do a lot of work to ensure you are reading the information correctly. In fact, not only will you be able to get a core count, but you can get all kinds of processor topology information. Not sure how it works in a VM though if you are using that environment.






            share|improve this answer













            You can use the CPUID instruction to query the processor directly (platform independent, though since you can't do inline asm in MSVC anymore for some compilers you'll need to use different functions to have access to it). The only downside is that as of a few years ago Intel and AMD handle this instruction differently, and you'll need to do a lot of work to ensure you are reading the information correctly. In fact, not only will you be able to get a core count, but you can get all kinds of processor topology information. Not sure how it works in a VM though if you are using that environment.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Jul 3 '15 at 15:07









            RyanPRyanP

            1,7411018




            1,7411018












            • CPUID is hardly platform independent. You yourself note that it doesn't always behave right, and you completely ignore other processors like ARM.

              – Raymond Chen
              Jul 3 '15 at 18:51

















            • CPUID is hardly platform independent. You yourself note that it doesn't always behave right, and you completely ignore other processors like ARM.

              – Raymond Chen
              Jul 3 '15 at 18:51
















            CPUID is hardly platform independent. You yourself note that it doesn't always behave right, and you completely ignore other processors like ARM.

            – Raymond Chen
            Jul 3 '15 at 18:51





            CPUID is hardly platform independent. You yourself note that it doesn't always behave right, and you completely ignore other processors like ARM.

            – Raymond Chen
            Jul 3 '15 at 18:51











            0














            Late answer with code:



            size_t myHardwareConcurrency()
            size_t concurrency=0;
            DWORD length=0;
            if(GetLogicalProcessorInformationEx(RelationAll,nullptr,&length)!=FALSE)
            return concurrency;
            if(GetLastError()!=ERROR_INSUFFICIENT_BUFFER)
            return concurrency;
            std::unique_ptr<void,void(*)(void*)>buffer(std::malloc(length),std::free);
            if(!buffer)
            return concurrency;
            unsigned char*mem=reinterpret_cast<unsigned char*>(buffer.get());
            if(GetLogicalProcessorInformationEx(RelationAll,reinterpret_cast<PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX>(mem),&length)==false)
            return concurrency;
            for(DWORD i=0;i<length;)
            auto*proc=reinterpret_cast<PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX>(mem+i);
            if(proc->Relationship==RelationProcessorCore)
            for(WORD group=0;group<proc->Processor.GroupCount;++group)
            for(KAFFINITY mask=proc->Processor.GroupMask[group].Mask;mask!=0;mask>>=1)
            concurrency+=mask&1;
            i+=proc->Size;
            return concurrency;


            It worked on my dual Xeon gold 6154 with Windows 64 bit system (2 procs * 18 cores/proc * 2 threads/core = 72 threads). The result is 72 both for 32 bit processes and for 64 bit processes.



            I do not have access to a system with a 32 bit Windows though.



            In case of error, it returns zero like std::thread::hardware_concurrency does.






            share|improve this answer

























            • According to MSDN you would just need to count the number of occurrences of RelationProcessorCore so the counting loop can be simplified to: if (proc->Relationship==RelationProcessorCore) ++concurrency;. This is because the number of groups a core belongs to is always 1 and the mask only contains a single bit denoting the position (or affinity) in that group. I guess it would also make counting under WoW64 emulation more robust...

              – klaus triendl
              Nov 13 '18 at 16:46












            • @klaustriendl I just edited the OP question to make a clear distinction between number of cores and number of threads. Although he used the word cores all along, the number he gave were for the number of hardware threads. Your suggestion would be correct to get the number of core, but the OP wanted the number of threads.

              – Arnaud
              Nov 13 '18 at 18:05











            • Thx @Arnaud Still you wouldn't have to loop through the groups as the group count is always 1. Anyway, to me the "number of active processor cores" was equivalent to the "number of logical processors", but reading further on PROCESSOR_RELATIONSHIP I understand that a core can have more than 1 logical processor. What happens under Wow64? Is the mask for logical processors 32 through 63 correct? Because the remarks state that it's incorrectly represented as duplicates for 0-31... (I guess for your specific machine these would be logical processors 32-35 of cores number 17+18?

              – klaus triendl
              Nov 13 '18 at 19:14











            • @klaustriendl On my machine (6 cores 12 threads 3930K), in x64 mode proc->Processor.GroupMask[0].Mask is 3 and I need to add 2 for each RelationProcessorCore

              – Arnaud
              Nov 13 '18 at 21:45











            • What do you mean exactly by x64 mode? Is it the 32-bit executable on a 64-bit OS, i.e. WoW64?

              – klaus triendl
              Nov 14 '18 at 8:35















            0














            Late answer with code:



            size_t myHardwareConcurrency()
            size_t concurrency=0;
            DWORD length=0;
            if(GetLogicalProcessorInformationEx(RelationAll,nullptr,&length)!=FALSE)
            return concurrency;
            if(GetLastError()!=ERROR_INSUFFICIENT_BUFFER)
            return concurrency;
            std::unique_ptr<void,void(*)(void*)>buffer(std::malloc(length),std::free);
            if(!buffer)
            return concurrency;
            unsigned char*mem=reinterpret_cast<unsigned char*>(buffer.get());
            if(GetLogicalProcessorInformationEx(RelationAll,reinterpret_cast<PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX>(mem),&length)==false)
            return concurrency;
            for(DWORD i=0;i<length;)
            auto*proc=reinterpret_cast<PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX>(mem+i);
            if(proc->Relationship==RelationProcessorCore)
            for(WORD group=0;group<proc->Processor.GroupCount;++group)
            for(KAFFINITY mask=proc->Processor.GroupMask[group].Mask;mask!=0;mask>>=1)
            concurrency+=mask&1;
            i+=proc->Size;
            return concurrency;


            It worked on my dual Xeon gold 6154 with Windows 64 bit system (2 procs * 18 cores/proc * 2 threads/core = 72 threads). The result is 72 both for 32 bit processes and for 64 bit processes.



            I do not have access to a system with a 32 bit Windows though.



            In case of error, it returns zero like std::thread::hardware_concurrency does.






            share|improve this answer

























            • According to MSDN you would just need to count the number of occurrences of RelationProcessorCore so the counting loop can be simplified to: if (proc->Relationship==RelationProcessorCore) ++concurrency;. This is because the number of groups a core belongs to is always 1 and the mask only contains a single bit denoting the position (or affinity) in that group. I guess it would also make counting under WoW64 emulation more robust...

              – klaus triendl
              Nov 13 '18 at 16:46












            • @klaustriendl I just edited the OP question to make a clear distinction between number of cores and number of threads. Although he used the word cores all along, the number he gave were for the number of hardware threads. Your suggestion would be correct to get the number of core, but the OP wanted the number of threads.

              – Arnaud
              Nov 13 '18 at 18:05











            • Thx @Arnaud Still you wouldn't have to loop through the groups as the group count is always 1. Anyway, to me the "number of active processor cores" was equivalent to the "number of logical processors", but reading further on PROCESSOR_RELATIONSHIP I understand that a core can have more than 1 logical processor. What happens under Wow64? Is the mask for logical processors 32 through 63 correct? Because the remarks state that it's incorrectly represented as duplicates for 0-31... (I guess for your specific machine these would be logical processors 32-35 of cores number 17+18?

              – klaus triendl
              Nov 13 '18 at 19:14











            • @klaustriendl On my machine (6 cores 12 threads 3930K), in x64 mode proc->Processor.GroupMask[0].Mask is 3 and I need to add 2 for each RelationProcessorCore

              – Arnaud
              Nov 13 '18 at 21:45











            • What do you mean exactly by x64 mode? Is it the 32-bit executable on a 64-bit OS, i.e. WoW64?

              – klaus triendl
              Nov 14 '18 at 8:35













            0












            0








            0







            Late answer with code:



            size_t myHardwareConcurrency()
            size_t concurrency=0;
            DWORD length=0;
            if(GetLogicalProcessorInformationEx(RelationAll,nullptr,&length)!=FALSE)
            return concurrency;
            if(GetLastError()!=ERROR_INSUFFICIENT_BUFFER)
            return concurrency;
            std::unique_ptr<void,void(*)(void*)>buffer(std::malloc(length),std::free);
            if(!buffer)
            return concurrency;
            unsigned char*mem=reinterpret_cast<unsigned char*>(buffer.get());
            if(GetLogicalProcessorInformationEx(RelationAll,reinterpret_cast<PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX>(mem),&length)==false)
            return concurrency;
            for(DWORD i=0;i<length;)
            auto*proc=reinterpret_cast<PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX>(mem+i);
            if(proc->Relationship==RelationProcessorCore)
            for(WORD group=0;group<proc->Processor.GroupCount;++group)
            for(KAFFINITY mask=proc->Processor.GroupMask[group].Mask;mask!=0;mask>>=1)
            concurrency+=mask&1;
            i+=proc->Size;
            return concurrency;


            It worked on my dual Xeon gold 6154 with Windows 64 bit system (2 procs * 18 cores/proc * 2 threads/core = 72 threads). The result is 72 both for 32 bit processes and for 64 bit processes.



            I do not have access to a system with a 32 bit Windows though.



            In case of error, it returns zero like std::thread::hardware_concurrency does.






            share|improve this answer















            Late answer with code:



            size_t myHardwareConcurrency()
            size_t concurrency=0;
            DWORD length=0;
            if(GetLogicalProcessorInformationEx(RelationAll,nullptr,&length)!=FALSE)
            return concurrency;
            if(GetLastError()!=ERROR_INSUFFICIENT_BUFFER)
            return concurrency;
            std::unique_ptr<void,void(*)(void*)>buffer(std::malloc(length),std::free);
            if(!buffer)
            return concurrency;
            unsigned char*mem=reinterpret_cast<unsigned char*>(buffer.get());
            if(GetLogicalProcessorInformationEx(RelationAll,reinterpret_cast<PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX>(mem),&length)==false)
            return concurrency;
            for(DWORD i=0;i<length;)
            auto*proc=reinterpret_cast<PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX>(mem+i);
            if(proc->Relationship==RelationProcessorCore)
            for(WORD group=0;group<proc->Processor.GroupCount;++group)
            for(KAFFINITY mask=proc->Processor.GroupMask[group].Mask;mask!=0;mask>>=1)
            concurrency+=mask&1;
            i+=proc->Size;
            return concurrency;


            It worked on my dual Xeon gold 6154 with Windows 64 bit system (2 procs * 18 cores/proc * 2 threads/core = 72 threads). The result is 72 both for 32 bit processes and for 64 bit processes.



            I do not have access to a system with a 32 bit Windows though.



            In case of error, it returns zero like std::thread::hardware_concurrency does.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 14 '18 at 10:53

























            answered Oct 9 '18 at 8:03









            ArnaudArnaud

            2,28122751




            2,28122751












            • According to MSDN you would just need to count the number of occurrences of RelationProcessorCore so the counting loop can be simplified to: if (proc->Relationship==RelationProcessorCore) ++concurrency;. This is because the number of groups a core belongs to is always 1 and the mask only contains a single bit denoting the position (or affinity) in that group. I guess it would also make counting under WoW64 emulation more robust...

              – klaus triendl
              Nov 13 '18 at 16:46












            • @klaustriendl I just edited the OP question to make a clear distinction between number of cores and number of threads. Although he used the word cores all along, the number he gave were for the number of hardware threads. Your suggestion would be correct to get the number of core, but the OP wanted the number of threads.

              – Arnaud
              Nov 13 '18 at 18:05











            • Thx @Arnaud Still you wouldn't have to loop through the groups as the group count is always 1. Anyway, to me the "number of active processor cores" was equivalent to the "number of logical processors", but reading further on PROCESSOR_RELATIONSHIP I understand that a core can have more than 1 logical processor. What happens under Wow64? Is the mask for logical processors 32 through 63 correct? Because the remarks state that it's incorrectly represented as duplicates for 0-31... (I guess for your specific machine these would be logical processors 32-35 of cores number 17+18?

              – klaus triendl
              Nov 13 '18 at 19:14











            • @klaustriendl On my machine (6 cores 12 threads 3930K), in x64 mode proc->Processor.GroupMask[0].Mask is 3 and I need to add 2 for each RelationProcessorCore

              – Arnaud
              Nov 13 '18 at 21:45











            • What do you mean exactly by x64 mode? Is it the 32-bit executable on a 64-bit OS, i.e. WoW64?

              – klaus triendl
              Nov 14 '18 at 8:35

















            • According to MSDN you would just need to count the number of occurrences of RelationProcessorCore so the counting loop can be simplified to: if (proc->Relationship==RelationProcessorCore) ++concurrency;. This is because the number of groups a core belongs to is always 1 and the mask only contains a single bit denoting the position (or affinity) in that group. I guess it would also make counting under WoW64 emulation more robust...

              – klaus triendl
              Nov 13 '18 at 16:46












            • @klaustriendl I just edited the OP question to make a clear distinction between number of cores and number of threads. Although he used the word cores all along, the number he gave were for the number of hardware threads. Your suggestion would be correct to get the number of core, but the OP wanted the number of threads.

              – Arnaud
              Nov 13 '18 at 18:05











            • Thx @Arnaud Still you wouldn't have to loop through the groups as the group count is always 1. Anyway, to me the "number of active processor cores" was equivalent to the "number of logical processors", but reading further on PROCESSOR_RELATIONSHIP I understand that a core can have more than 1 logical processor. What happens under Wow64? Is the mask for logical processors 32 through 63 correct? Because the remarks state that it's incorrectly represented as duplicates for 0-31... (I guess for your specific machine these would be logical processors 32-35 of cores number 17+18?

              – klaus triendl
              Nov 13 '18 at 19:14











            • @klaustriendl On my machine (6 cores 12 threads 3930K), in x64 mode proc->Processor.GroupMask[0].Mask is 3 and I need to add 2 for each RelationProcessorCore

              – Arnaud
              Nov 13 '18 at 21:45











            • What do you mean exactly by x64 mode? Is it the 32-bit executable on a 64-bit OS, i.e. WoW64?

              – klaus triendl
              Nov 14 '18 at 8:35
















            According to MSDN you would just need to count the number of occurrences of RelationProcessorCore so the counting loop can be simplified to: if (proc->Relationship==RelationProcessorCore) ++concurrency;. This is because the number of groups a core belongs to is always 1 and the mask only contains a single bit denoting the position (or affinity) in that group. I guess it would also make counting under WoW64 emulation more robust...

            – klaus triendl
            Nov 13 '18 at 16:46






            According to MSDN you would just need to count the number of occurrences of RelationProcessorCore so the counting loop can be simplified to: if (proc->Relationship==RelationProcessorCore) ++concurrency;. This is because the number of groups a core belongs to is always 1 and the mask only contains a single bit denoting the position (or affinity) in that group. I guess it would also make counting under WoW64 emulation more robust...

            – klaus triendl
            Nov 13 '18 at 16:46














            @klaustriendl I just edited the OP question to make a clear distinction between number of cores and number of threads. Although he used the word cores all along, the number he gave were for the number of hardware threads. Your suggestion would be correct to get the number of core, but the OP wanted the number of threads.

            – Arnaud
            Nov 13 '18 at 18:05





            @klaustriendl I just edited the OP question to make a clear distinction between number of cores and number of threads. Although he used the word cores all along, the number he gave were for the number of hardware threads. Your suggestion would be correct to get the number of core, but the OP wanted the number of threads.

            – Arnaud
            Nov 13 '18 at 18:05













            Thx @Arnaud Still you wouldn't have to loop through the groups as the group count is always 1. Anyway, to me the "number of active processor cores" was equivalent to the "number of logical processors", but reading further on PROCESSOR_RELATIONSHIP I understand that a core can have more than 1 logical processor. What happens under Wow64? Is the mask for logical processors 32 through 63 correct? Because the remarks state that it's incorrectly represented as duplicates for 0-31... (I guess for your specific machine these would be logical processors 32-35 of cores number 17+18?

            – klaus triendl
            Nov 13 '18 at 19:14





            Thx @Arnaud Still you wouldn't have to loop through the groups as the group count is always 1. Anyway, to me the "number of active processor cores" was equivalent to the "number of logical processors", but reading further on PROCESSOR_RELATIONSHIP I understand that a core can have more than 1 logical processor. What happens under Wow64? Is the mask for logical processors 32 through 63 correct? Because the remarks state that it's incorrectly represented as duplicates for 0-31... (I guess for your specific machine these would be logical processors 32-35 of cores number 17+18?

            – klaus triendl
            Nov 13 '18 at 19:14













            @klaustriendl On my machine (6 cores 12 threads 3930K), in x64 mode proc->Processor.GroupMask[0].Mask is 3 and I need to add 2 for each RelationProcessorCore

            – Arnaud
            Nov 13 '18 at 21:45





            @klaustriendl On my machine (6 cores 12 threads 3930K), in x64 mode proc->Processor.GroupMask[0].Mask is 3 and I need to add 2 for each RelationProcessorCore

            – Arnaud
            Nov 13 '18 at 21:45













            What do you mean exactly by x64 mode? Is it the 32-bit executable on a 64-bit OS, i.e. WoW64?

            – klaus triendl
            Nov 14 '18 at 8:35





            What do you mean exactly by x64 mode? Is it the 32-bit executable on a 64-bit OS, i.e. WoW64?

            – klaus triendl
            Nov 14 '18 at 8:35

















            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f31209256%2freliable-way-to-programmatically-get-the-number-of-hardware-threads-on-windows%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            How to how show current date and time by default on contact form 7 in WordPress without taking input from user in datetimepicker

            Syphilis

            Darth Vader #20