ClickHouse/dbms/src/Common/getNumberOfPhysicalCPUCores.cpp

66 lines
2.3 KiB
C++
Raw Normal View History

#include <Common/getNumberOfPhysicalCPUCores.h>
#include <thread>
2018-05-07 14:35:45 +00:00
#include <fstream>
#if defined(__x86_64__)
#include <cpuid/libcpuid.h>
#include <Common/Exception.h>
namespace DB { namespace ErrorCodes { extern const int CPUID_ERROR; }}
#endif
unsigned getNumberOfPhysicalCPUCores()
{
2018-05-08 08:04:23 +00:00
#if defined(__linux__)
2018-05-08 09:43:31 +00:00
/// On Linux we try to look at Cgroups limit if it is available.
2018-05-07 14:35:45 +00:00
std::ifstream cgroup_read_in("/sys/fs/cgroup/cpu/cpu.cfs_quota_us");
if (cgroup_read_in.is_open())
{
2018-05-07 16:35:26 +00:00
std::string allocated_cpus_share_str{ std::istreambuf_iterator<char>(cgroup_read_in), std::istreambuf_iterator<char>() };
int allocated_cpus_share_int = std::stoi(allocated_cpus_share_str);
2018-05-07 14:35:45 +00:00
cgroup_read_in.close();
// If a valid value is present
2018-05-08 09:43:31 +00:00
if (allocated_cpus_share_int > 0)
2018-05-07 14:35:45 +00:00
{
2018-05-08 09:43:31 +00:00
unsigned allocated_cpus = (allocated_cpus_share_int + 999) / 1000;
2018-05-07 16:35:26 +00:00
return allocated_cpus;
2018-05-07 14:35:45 +00:00
}
}
2018-05-08 08:04:23 +00:00
#endif
2018-05-07 14:35:45 +00:00
2018-05-08 09:43:31 +00:00
#if defined(__x86_64__)
cpu_raw_data_t raw_data;
if (0 != cpuid_get_raw_data(&raw_data))
throw DB::Exception("Cannot cpuid_get_raw_data: " + std::string(cpuid_error()), DB::ErrorCodes::CPUID_ERROR);
cpu_id_t data;
if (0 != cpu_identify(&raw_data, &data))
throw DB::Exception("Cannot cpu_identify: " + std::string(cpuid_error()), DB::ErrorCodes::CPUID_ERROR);
/// On Xen VMs, libcpuid returns wrong info (zero number of cores). Fallback to alternative method.
if (data.num_logical_cpus == 0)
return std::thread::hardware_concurrency();
unsigned res = data.num_cores * data.total_logical_cpus / data.num_logical_cpus;
/// 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.
if (res != 0)
return res;
#endif
/// 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();
}