From 93321e2a31ea97383ad608ce3b7521adccfbdfce Mon Sep 17 00:00:00 2001 From: obdev Date: Thu, 12 Dec 2024 11:19:00 +0000 Subject: [PATCH] Fix cpu topo --- deps/oblib/src/common/ob_target_specific.cpp | 20 ++++++ deps/oblib/src/common/ob_target_specific.h | 20 +----- deps/oblib/src/lib/cpu/ob_cpu_topology.cpp | 75 +++++++++++++------- deps/oblib/src/lib/cpu/ob_cpu_topology.h | 7 +- src/observer/ob_server.cpp | 2 + 5 files changed, 75 insertions(+), 49 deletions(-) diff --git a/deps/oblib/src/common/ob_target_specific.cpp b/deps/oblib/src/common/ob_target_specific.cpp index 2289a7012..58cd0c904 100644 --- a/deps/oblib/src/common/ob_target_specific.cpp +++ b/deps/oblib/src/common/ob_target_specific.cpp @@ -11,11 +11,31 @@ */ #define USING_LOG_PREFIX COMMON +#include "common/ob_target_specific.h" namespace oceanbase { namespace common { +uint32_t arches; +void init_arches() +{ + arches = 0; + const CpuFlagSet flags; + if (flags.have_flag(CpuFlag::SSE4_2)) { + arches |= static_cast(ObTargetArch::SSE42); + } + if (flags.have_flag(CpuFlag::AVX)) { + arches |= static_cast(ObTargetArch::AVX); + } + if (flags.have_flag(CpuFlag::AVX2)) { + arches |= static_cast(ObTargetArch::AVX2); + } + if (flags.have_flag(CpuFlag::AVX512BW)) { + arches |= static_cast(ObTargetArch::AVX512); + } +} + } // namespace common } // namespace oceanbase \ No newline at end of file diff --git a/deps/oblib/src/common/ob_target_specific.h b/deps/oblib/src/common/ob_target_specific.h index 3661066b5..c2982aca7 100644 --- a/deps/oblib/src/common/ob_target_specific.h +++ b/deps/oblib/src/common/ob_target_specific.h @@ -215,27 +215,11 @@ OB_DECLARE_AVX512_SPECIFIC_CODE( #endif -OB_INLINE uint32_t get_supported_archs() -{ - uint32_t result = 0; - if (CpuFlagSet::get_instance().have_flag(CpuFlag::SSE4_2)) { - result |= static_cast(ObTargetArch::SSE42); - } - if (CpuFlagSet::get_instance().have_flag(CpuFlag::AVX)) { - result |= static_cast(ObTargetArch::AVX); - } - if (CpuFlagSet::get_instance().have_flag(CpuFlag::AVX2)) { - result |= static_cast(ObTargetArch::AVX2); - } - if (CpuFlagSet::get_instance().have_flag(CpuFlag::AVX512BW)) { - result |= static_cast(ObTargetArch::AVX512); - } - return result; -} +void init_arches(); +extern uint32_t arches; OB_INLINE bool is_arch_supported(ObTargetArch arch) { - static uint32_t arches = get_supported_archs(); return arch == ObTargetArch::Default || (arches & static_cast(arch)); } diff --git a/deps/oblib/src/lib/cpu/ob_cpu_topology.cpp b/deps/oblib/src/lib/cpu/ob_cpu_topology.cpp index a58ce5809..489fb8905 100644 --- a/deps/oblib/src/lib/cpu/ob_cpu_topology.cpp +++ b/deps/oblib/src/lib/cpu/ob_cpu_topology.cpp @@ -10,10 +10,10 @@ * See the Mulan PubL v2 for more details. */ -#include "lib/cpu/ob_cpu_topology.h" +#define USING_LOG_PREFIX COMMON -#include "lib/ob_define.h" -#include "lib/container/ob_bit_set.h" +#include "lib/cpu/ob_cpu_topology.h" +#include "lib/oblog/ob_log_module.h" namespace oceanbase { namespace common { @@ -30,12 +30,6 @@ static bool cpu_have_avx2(); static bool cpu_have_avxf(); static bool cpu_have_avx512bw(); -const CpuFlagSet& CpuFlagSet::get_instance() -{ - static CpuFlagSet instance; - return instance; -} - bool CpuFlagSet::have_flag(const CpuFlag flag) const { return flags_ & (1 << (int)flag); @@ -43,46 +37,73 @@ bool CpuFlagSet::have_flag(const CpuFlag flag) const CpuFlagSet::CpuFlagSet() : flags_(0) { - uint64_t flags_from_cpu = init_from_cpu(); - uint64_t flags_from_os = init_from_os(); - if (flags_from_cpu != flags_from_os) { + int ret = OB_SUCCESS; + uint64_t flags_from_cpu, flags_from_os; + init_from_cpu(flags_from_cpu); + if (OB_FAIL(init_from_os(flags_from_os))) { + COMMON_LOG(WARN, "failed to init cpu flags from os", K(ret)); + // fork failed or grep failed + // use flags from cpu + flags_ = flags_from_cpu; + } else if (flags_from_cpu != flags_from_os) { COMMON_LOG_RET(ERROR, OB_ERR_SYS, "There is a mismatch between the cpu flags from cpu and those from os, " - "ISA extension like avx512bw may be not supported by your virtualization setup"); + "ISA extension like avx512bw may be not supported by the virtualization setup", K(flags_from_cpu), K(flags_from_os)); flags_ = flags_from_cpu & flags_from_os; } else { flags_ = flags_from_cpu; } +#define LOG_CPUFLAG(flag) \ + if (have_flag(CpuFlag::flag)) { \ + _LOG_INFO("#flag is supported"); \ + } else { \ + _LOG_WARN("#flag is not supported"); \ + } + LOG_CPUFLAG(SSE4_2) + LOG_CPUFLAG(AVX) + LOG_CPUFLAG(AVX2) + LOG_CPUFLAG(AVX512BW) +#undef LOG_CPUFLAG } -uint64_t CpuFlagSet::init_from_cpu() +void CpuFlagSet::init_from_cpu(uint64_t& flags) { - uint64_t flags = 0; -#define cpu_have(flag, FLAG) \ + flags = 0; +#define CPU_HAVE(flag, FLAG) \ if (cpu_have_##flag()) { \ flags |= (1 << (int)CpuFlag::FLAG); \ } - cpu_have(sse42, SSE4_2); - cpu_have(avx, AVX); - cpu_have(avx2, AVX2); - cpu_have(avx512bw, AVX512BW); - return flags; + CPU_HAVE(sse42, SSE4_2); + CPU_HAVE(avx, AVX); + CPU_HAVE(avx2, AVX2); + CPU_HAVE(avx512bw, AVX512BW); +#undef CPU_HAVE } -uint64_t CpuFlagSet::init_from_os() +int CpuFlagSet::init_from_os(uint64_t& flags) { - uint64_t flags = 0; int ret = OB_SUCCESS; - const char* const CPU_FLAG_CMDS[(int)CpuFlag::MAX] = { - "grep -E ' sse4_2( |$)' /proc/cpuinfo", + flags = 0; + const char* const CPU_FLAG_CMDS[(int)CpuFlag::MAX] = {"grep -E ' sse4_2( |$)' /proc/cpuinfo", "grep -E ' avx( |$)' /proc/cpuinfo", "grep -E ' avx2( |$)' /proc/cpuinfo", "grep -E ' avx512bw( |$)' /proc/cpuinfo"}; for (int i = 0; i < (int)CpuFlag::MAX; ++i) { - flags |= (0 == system(CPU_FLAG_CMDS[i])) << i; + int system_ret = system(CPU_FLAG_CMDS[i]); + if (system_ret != 0) { + if (-1 != system_ret && 1 == WEXITSTATUS(system_ret)) { + // not found + COMMON_LOG(WARN, "cpu flag is not found", K(CPU_FLAG_CMDS[i])); + } else { + ret = OB_ERR_SYS; + _LOG_WARN("system(\"%s\") returns %d", CPU_FLAG_CMDS[i], system_ret); + } + } else { + flags |= (1 << i); + } } - return flags; + return ret; } #if defined(__x86_64__) diff --git a/deps/oblib/src/lib/cpu/ob_cpu_topology.h b/deps/oblib/src/lib/cpu/ob_cpu_topology.h index cfff2379d..b2b089381 100644 --- a/deps/oblib/src/lib/cpu/ob_cpu_topology.h +++ b/deps/oblib/src/lib/cpu/ob_cpu_topology.h @@ -29,12 +29,11 @@ enum class CpuFlag { SSE4_2 = 0, AVX, AVX2, AVX512BW, MAX }; class CpuFlagSet { public: DISABLE_COPY_ASSIGN(CpuFlagSet); - static const CpuFlagSet& get_instance(); bool have_flag(const CpuFlag flag) const; -private: CpuFlagSet(); - uint64_t init_from_cpu(); - uint64_t init_from_os(); +private: + void init_from_cpu(uint64_t& flags); + int init_from_os(uint64_t& flags); int64_t flags_; }; diff --git a/src/observer/ob_server.cpp b/src/observer/ob_server.cpp index d241fdf85..35201fa10 100644 --- a/src/observer/ob_server.cpp +++ b/src/observer/ob_server.cpp @@ -146,6 +146,7 @@ #endif #include "storage/backup/ob_backup_meta_cache.h" #include "lib/stat/ob_diagnostic_info_container.h" +#include "common/ob_target_specific.h" using namespace oceanbase::lib; using namespace oceanbase::common; @@ -297,6 +298,7 @@ int ObServer::init(const ObServerOptions &opts, const ObPLogWriterCfg &log_cfg) DBA_STEP_RESET(server_start); int ret = OB_SUCCESS; opts_ = opts; + init_arches(); scramble_rand_.init(static_cast(start_time_), static_cast(start_time_ / 2)); // start ObTimerService first, because some timers depend on it