2017-04-01 09:19:00 +00:00
|
|
|
#include <Common/getNumberOfPhysicalCPUCores.h>
|
2016-06-30 20:35:07 +00:00
|
|
|
#include <thread>
|
2016-01-13 02:11:40 +00:00
|
|
|
|
2020-04-16 12:31:57 +00:00
|
|
|
#if !defined(ARCADIA_BUILD)
|
|
|
|
# include <Common/config.h>
|
|
|
|
#else
|
|
|
|
# include <libcpuid/libcpuid.h>
|
|
|
|
#endif
|
|
|
|
|
2019-01-28 13:16:08 +00:00
|
|
|
#if USE_CPUID
|
2020-04-16 12:31:57 +00:00
|
|
|
# include <libcpuid/libcpuid.h>
|
2019-01-28 13:24:55 +00:00
|
|
|
#elif USE_CPUINFO
|
2020-04-16 12:31:57 +00:00
|
|
|
# include <cpuinfo.h>
|
2016-01-13 02:11:40 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
unsigned getNumberOfPhysicalCPUCores()
|
|
|
|
{
|
2019-01-28 13:16:08 +00:00
|
|
|
#if USE_CPUID
|
2017-04-01 07:20:54 +00:00
|
|
|
cpu_raw_data_t raw_data;
|
|
|
|
cpu_id_t data;
|
2016-01-13 02:11:40 +00:00
|
|
|
|
2017-04-01 07:20:54 +00:00
|
|
|
/// On Xen VMs, libcpuid returns wrong info (zero number of cores). Fallback to alternative method.
|
2019-11-11 21:01:55 +00:00
|
|
|
/// Also, libcpuid does not support some CPUs like AMD Hygon C86 7151.
|
|
|
|
if (0 != cpuid_get_raw_data(&raw_data) || 0 != cpu_identify(&raw_data, &data) || data.num_logical_cpus == 0)
|
2017-04-01 07:20:54 +00:00
|
|
|
return std::thread::hardware_concurrency();
|
2016-06-30 20:35:07 +00:00
|
|
|
|
2017-05-24 18:38:18 +00:00
|
|
|
unsigned res = data.num_cores * data.total_logical_cpus / data.num_logical_cpus;
|
2016-01-13 02:11:40 +00:00
|
|
|
|
2017-05-24 18:38:18 +00:00
|
|
|
/// Also, libcpuid gives strange result on Google Compute Engine VMs.
|
2017-05-24 18:49:30 +00:00
|
|
|
/// Example:
|
|
|
|
/// num_cores = 12, /// number of physical cores on current CPU socket
|
|
|
|
/// total_logical_cpus = 1, /// total number of logical cores on all sockets
|
|
|
|
/// num_logical_cpus = 24. /// number of logical cores on current CPU socket
|
|
|
|
/// It means two-way hyper-threading (24 / 12), but contradictory, 'total_logical_cpus' == 1.
|
|
|
|
|
2017-05-24 18:38:18 +00:00
|
|
|
if (res != 0)
|
|
|
|
return res;
|
2019-11-11 21:01:55 +00:00
|
|
|
|
2019-01-28 13:24:55 +00:00
|
|
|
#elif USE_CPUINFO
|
2019-01-28 13:16:08 +00:00
|
|
|
uint32_t cores = 0;
|
|
|
|
if (cpuinfo_initialize())
|
|
|
|
cores = cpuinfo_get_cores_count();
|
|
|
|
|
|
|
|
if (cores)
|
2019-11-11 20:56:11 +00:00
|
|
|
return cores;
|
2016-01-13 02:11:40 +00:00
|
|
|
#endif
|
2017-05-24 18:38:18 +00:00
|
|
|
|
|
|
|
/// As a fallback (also for non-x86 architectures) assume there are no hyper-threading on the system.
|
|
|
|
/// (Actually, only Aarch64 is supported).
|
|
|
|
return std::thread::hardware_concurrency();
|
2016-01-13 02:11:40 +00:00
|
|
|
}
|