<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/72267>72267</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            `std::thread::hardware_concurrency` return incorrect count threads in NUMA multi-CPU configuration
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          GermanAizek
      </td>
    </tr>
</table>

<pre>
    I have Xeon 2xE5-2699v4 Windows detect 88 threads and 44 cores. I noticed that all binaries that are compiled using Clang incorrectly detect count threads on multi 2x 4x socket motherboards with NUMA architecture. Therefore, I propose my own version, which is modified and works on all systems. I read on visual studio forum and realized that this is a WinAPI problem.

```cpp
#include <iostream>
#include <Windows.h>
#include <thread>

// modified my function
size_t MyHardwareConcurrency() noexcept
{
        DWORD length = 0;
        size_t concurrency = 0;
        const auto validConcurrency = [&concurrency]() noexcept -> size_t {
                if (concurrency == 0)
                        return std::thread::hardware_concurrency();
                else
                        return concurrency;
                };
        if (GetLogicalProcessorInformationEx(RelationAll, nullptr, &length) != FALSE) {
                return validConcurrency();
        }
        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
                return validConcurrency();
        }
        std::unique_ptr<void, void (*)(void*)> buffer(std::malloc(length), std::free);
        if (!buffer) {
                return validConcurrency();
        }
        auto* mem = reinterpret_cast<unsigned char*>(buffer.get());
        if (GetLogicalProcessorInformationEx(
                RelationAll, reinterpret_cast<PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX>(mem), &length) == false) {
                return validConcurrency();
        }
        DWORD i = 0;
        while (i < length) {
                const 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 validConcurrency();
}

uint32_t get_thread_count()
{
    static const uint32_t g_count = []()
 {
#ifdef _WIN32
            ::SYSTEM_INFO sysInfo;
 ::GetNativeSystemInfo(&sysInfo);
            return sysInfo.dwNumberOfProcessors;
#else
            return ::sysconf(_SC_NPROCESSORS_ONLN);
#endif
        }();

 return g_count;
}

// in llvm-project/libcxx/src/thread.cpp
DWORD getWin32Count()
{
        SYSTEM_INFO info;
        GetSystemInfo(&info);
        return info.dwNumberOfProcessors;
}

int main()
{
    std::cout << MyHardwareConcurrency() << '\n';
    std::cout << get_thread_count() << '\n';
    std::cout << getWin32Count() << '\n';
}
```

Result: MSVC v19.37 latest
```
88
44
44
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJysV01z4jwS_jXKpWsoW-bLBw7EQJbahKQgs_O-J0rYbayNLLGSDMn8-i35ExgyM7s1FIWx1Hq6--lWt8SM4XuJOCGDezKY3bHCZkpPHlDnTE75d3y726nkY7KEjB0R_kIlgb7PB1_oMAyPffjGZaJOBhK0GFsYj8FmGlligMkE-n2IlUbTgyVIZXmMCdiMWWBCwI5LpjmaekQjxCo_cIEJFIbLPUSCyT1wGSutMbbio9ESq0LaVpGSkBfCcqDv0H8Ho-I3tJArm6HeKaYTAyduM1h9fZoC03HGHUihsQevGWpMlUZCI1jCQauDMgj5B6iThCNqw5V0c6eMxxlwA7lKeMoxKd07Kf1W6nfumA9jMS9ddXa54SM3BRNgbJFwBanSRV6u08gE_95wYTNuHDRzZE5fSjN2AvMe8WbEm9a_Q6_6xodDPUIDLmNRJAgkiLgyViPLSTC_NV2HqZd9Ml9x2U3WIgtCF53L-QekhYyt46QUMPw7bi08ffyD6eTENEZKxoXWKOMPQseEhiAVvsd4sDXi6L5REM6-Pa9nIFDubQYkmIFHgm62ho47wB9lYiWNBVZYBUcmeBJdCbuUpsMzCDKYXZkFX0gwh1rZuXXEC3kKhI6vLKiMoOG5IPFCjbbQEoxNSDAlwbTh0_3PanK28TU7584QL0Rh8Dbu-crLNWQ0Ox-pbH5A-6j2PGbiRasYjVF6KVOlc-ZiN38ndLxGUb5MhXD5LQshDla7v4QOq6A4ngj1nceL6eNmXr5fUlSbd83-De9Gsxs2MmPnWitdB6VWNl-vn9fb5WrzdbFYRsv56nV7_3WxmK__lAFtlArJ_1Pg1jkeREfFE-e_e0IJMHUYdFxNlC_BHHZFmqKzuEXJmRAqJnTc0uZg2ulUI14ZUzFAqN-A_Rm_3E4gdAo55mX-a-TSoj5otNuYGUuCqJBluU8gzph2TgVzQseVGb092lrBLXN_I6nOPbhKsBu2vGz-3rzOn7aPzw_LaPq4fVk_R_PNpoz94nn9NH1dPq-2878qG3PMa2YvE7Takilze-cP8VhVJv5jwTllXKDjws1FcGbFpdauMLlwHLSKP4vH_8wBEHoP_MfaUcXIqXIVrSHfZPzQUNSMtdGLyr73g_HEC1OlHVpJw16r4tBS0b5G0Ohq8XoPbi5yvdlJEnpP6H0pf1tLp-if08ViuVq-_g05M2-lsk_Qn5h5I4MadTDrle_Bfb2uqh9eNxDMy-8M_E9NqMLVlXh67-RrvCH41_W2rbpXg1cjl6-8wW3c2vDv-Fn6_WbOdivcb8GlDejWwh7ttuo-2_KYVC-7bL8AAMYyy2OocrVbXq1q-2fTMet1HYU04GmCKWy_LVcB7WCbT1X86vR2yewOSK5gtB7UIg9oV8zyI27KA1Qp4lQOG_kzp88VNC23kuolp1WR71A_p23KmI4sGnTN9QZIZYn5MLGSKaHj7Sbartq9uNk-rx5XF-TTAGXC00tAF5LrwlLO11pqbj8LYX3c4hKEOOZfDlr9G2NL6ELwXfz-TujC6JjQRRXdXnsQrMrVHu03LgMafRp04oXn4eDnsSBe-ID2OgL8iv4uOfmvKb90jksLOePyJ-lY98tYFS79IldjfnayrEUIHZFBJN0j-BXc7b3xfyJds_0TmI6L5hR_Ts0aTSEsCabwtPlXBEc_7AUjEMyisTeXjetG2-9fPluxu2QSJGEQsjuc-MMwDEf9cRDeZZMw9YasTweDvp-GqT-IgyTwEpaGA8aCkPl3fEI9Gvi-3_cHfjAIe8zz_T7SlAaMjf3hiPQ9zBkXPZejPaX3d9yYAicjSoejO8F2KEx5l6RU4gnKSUKpu1rqSZnXu2JvSN8T3FjToVhuBU7I0Pv9I_TQgzYb6yvi1c2Qy-rSV14Pv0QvX121S_m-0GUnvCu0mGTWHozTUu6-PbdZsevFKnf7Thybx9luLF0yhC5Kl_8bAAD__wcwdNM">