2020-05-08 14:11:19 +00:00
|
|
|
#include "getNumberOfPhysicalCPUCores.h"
|
2020-04-16 12:31:57 +00:00
|
|
|
|
2022-01-18 06:51:13 +00:00
|
|
|
#include <Common/config.h>
|
2021-12-31 08:39:59 +00:00
|
|
|
#if defined(OS_LINUX)
|
|
|
|
# include <cmath>
|
|
|
|
# include <fstream>
|
|
|
|
#endif
|
2016-01-13 02:11:40 +00:00
|
|
|
|
2020-05-08 14:11:19 +00:00
|
|
|
#include <thread>
|
|
|
|
|
2021-12-31 08:39:59 +00:00
|
|
|
#if defined(OS_LINUX)
|
2022-04-15 20:54:08 +00:00
|
|
|
static int readFrom(const char * filename, int default_value)
|
2021-12-31 08:39:59 +00:00
|
|
|
{
|
2022-04-15 20:54:08 +00:00
|
|
|
std::ifstream infile(filename);
|
|
|
|
if (!infile.is_open())
|
|
|
|
return default_value;
|
|
|
|
int idata;
|
|
|
|
if (infile >> idata)
|
|
|
|
return idata;
|
|
|
|
else
|
|
|
|
return default_value;
|
|
|
|
}
|
2021-12-31 08:39:59 +00:00
|
|
|
|
2022-04-15 20:54:08 +00:00
|
|
|
/// Try to look at cgroups limit if it is available.
|
|
|
|
static unsigned getCGroupLimitedCPUCores(unsigned default_cpu_count)
|
|
|
|
{
|
2021-12-31 08:39:59 +00:00
|
|
|
unsigned quota_count = default_cpu_count;
|
2022-04-15 20:54:08 +00:00
|
|
|
/// Return the number of milliseconds per period process is guaranteed to run.
|
|
|
|
/// -1 for no quota
|
|
|
|
int cgroup_quota = readFrom("/sys/fs/cgroup/cpu/cpu.cfs_quota_us", -1);
|
|
|
|
int cgroup_period = readFrom("/sys/fs/cgroup/cpu/cpu.cfs_period_us", -1);
|
2021-12-31 08:39:59 +00:00
|
|
|
if (cgroup_quota > -1 && cgroup_period > 0)
|
|
|
|
quota_count = ceil(static_cast<float>(cgroup_quota) / static_cast<float>(cgroup_period));
|
|
|
|
|
2022-03-31 15:21:54 +00:00
|
|
|
return std::min(default_cpu_count, quota_count);
|
2021-12-31 08:39:59 +00:00
|
|
|
}
|
2022-04-15 20:54:08 +00:00
|
|
|
#endif
|
2016-01-13 02:11:40 +00:00
|
|
|
|
2022-04-15 20:56:51 +00:00
|
|
|
static unsigned getNumberOfPhysicalCPUCoresImpl()
|
2016-01-13 02:11:40 +00:00
|
|
|
{
|
2022-04-16 00:08:06 +00:00
|
|
|
unsigned cpu_count = std::thread::hardware_concurrency();
|
2020-07-16 23:12:47 +00:00
|
|
|
|
2022-04-16 00:08:06 +00:00
|
|
|
/// Most of x86_64 CPUs have 2-way Hyper-Threading
|
|
|
|
/// Aarch64 and RISC-V don't have SMT so far.
|
|
|
|
/// POWER has SMT and it can be multiple way (like 8-way), but we don't know how ClickHouse really behaves, so use all of them.
|
2020-07-16 23:12:47 +00:00
|
|
|
|
2022-04-16 00:08:06 +00:00
|
|
|
#if defined(__x86_64__)
|
|
|
|
/// Let's limit ourself to the number of physical cores.
|
|
|
|
/// But if the number of logical cores is small - maybe it is a small machine
|
|
|
|
/// or very limited cloud instance and it is reasonable to use all the cores.
|
|
|
|
if (cpu_count >= 8)
|
|
|
|
cpu_count /= 2;
|
2021-12-31 08:39:59 +00:00
|
|
|
#endif
|
2020-07-16 23:12:47 +00:00
|
|
|
|
2021-12-31 08:39:59 +00:00
|
|
|
#if defined(OS_LINUX)
|
2022-04-15 20:54:08 +00:00
|
|
|
cpu_count = getCGroupLimitedCPUCores(cpu_count);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return cpu_count;
|
2016-01-13 02:11:40 +00:00
|
|
|
}
|
2022-04-15 20:56:51 +00:00
|
|
|
|
|
|
|
unsigned getNumberOfPhysicalCPUCores()
|
|
|
|
{
|
|
|
|
/// Calculate once.
|
|
|
|
static auto res = getNumberOfPhysicalCPUCoresImpl();
|
|
|
|
return res;
|
|
|
|
}
|