From 781dccda979b392cb6dc8f9b3e65bbf5f0b99373 Mon Sep 17 00:00:00 2001 From: zhaolichang Date: Mon, 9 Dec 2024 11:53:48 +0800 Subject: [PATCH 1/7] modify the method of obtaining cpu frequency 1. use dmidecode to obtain cpu frequency when cpufreq file does not exist 2. merge duplicate code in cpu frequency --- include/oeaware/utils.h | 2 + src/common/utils.cpp | 51 +++++++++++++++++++ src/plugin/scenario/analysis/analysis/env.cpp | 39 ++++++-------- src/plugin/scenario/analysis/analysis/env.h | 1 + src/plugin/tune/docker/cpu_burst.cpp | 37 ++++++-------- src/plugin/tune/docker/cpu_burst.h | 1 + 6 files changed, 87 insertions(+), 44 deletions(-) diff --git a/include/oeaware/utils.h b/include/oeaware/utils.h index 98e9c5c..48fc7af 100644 --- a/include/oeaware/utils.h +++ b/include/oeaware/utils.h @@ -32,6 +32,8 @@ std::vector SplitString(const std::string &str, const std::string & bool CreateDir(const std::string &path); bool SetDataListTopic(DataList *dataList, const std::string &instanceName, const std::string &topicName, const std::string ¶ms); +uint64_t GetCpuCycles(int cpu); +uint64_t GetCpuFreqByDmi(); } #endif \ No newline at end of file diff --git a/src/common/utils.cpp b/src/common/utils.cpp index 8f63a70..79bdc49 100644 --- a/src/common/utils.cpp +++ b/src/common/utils.cpp @@ -17,6 +17,8 @@ #include #include #include +#include +#include namespace oeaware { const static int ST_MODE_MASK = 0777; @@ -201,4 +203,53 @@ bool SetDataListTopic(DataList *dataList, const std::string &instanceName, const return true; } +uint64_t GetCpuCycles(int cpu) +{ + std::string freqPath = "/sys/devices/system/cpu/cpu" + std::to_string(cpu) + "/cpufreq/scaling_cur_freq"; + std::ifstream freqFile(freqPath); + + if (!freqFile.is_open()) { + return 0; + } + + uint64_t freq; + freqFile >> freq; + freqFile.close(); + + if (freqFile.fail()) { + return 0; + } + + return freq * 1000; // 1000: kHz to Hz +} + +uint64_t GetCpuFreqByDmi() +{ + FILE *pipe = popen("dmidecode -t processor | grep 'Max Speed' | head -n 1 | awk '{print $3}'", "r"); + if (!pipe) { + std::cout << "failed to run dmidecode" << std::endl; + return 0; + } + + char buffer[128]; + if (fgets(buffer, sizeof(buffer), pipe) == nullptr) { + std::cout << "failed to get cpufreq by dmidecode" << std::endl; + pclose(pipe); + return 0; + } + pclose(pipe); + + std::string str(buffer); + str.erase(str.find_last_not_of(" \t\n\r") + 1); + + for (char c : str) { + if (!std::isdigit(c)) { + std::cerr << "invalid CPU frequency format: " << str << std::endl; + return 0; + } + } + + return std::stoull(buffer) * 1000000; // 1000000: MHz to Hz +} + } diff --git a/src/plugin/scenario/analysis/analysis/env.cpp b/src/plugin/scenario/analysis/analysis/env.cpp index a3a5457..63d352f 100644 --- a/src/plugin/scenario/analysis/analysis/env.cpp +++ b/src/plugin/scenario/analysis/analysis/env.cpp @@ -13,7 +13,10 @@ #include #include #include +#include +#include "oeaware/utils.h" #include "env.h" + unsigned long GetPageMask() { static unsigned long pageMask = 0; @@ -29,32 +32,17 @@ unsigned long GetPageMask() return pageMask; } -static uint64_t GetCpuCycles(int cpu) -{ - std::string freqPath = "/sys/devices/system/cpu/cpu" + std::to_string(cpu) + "/cpufreq/scaling_cur_freq"; - std::ifstream freqFile(freqPath); - - if (!freqFile.is_open()) { - return 0; - } - - uint64_t freq; - freqFile >> freq; - freqFile.close(); - - if (freqFile.fail()) { - return 0; - } - - return freq * 1000; // 1000: kHz to Hz -} - -static void InitCpuCycles(std::vector &maxCycles, uint64_t &sysMaxCycles) +static void InitCpuCycles(std::vector &maxCycles, uint64_t &sysMaxCycles, uint64_t &maxCpuFreqByDmi) { for (int cpu = 0; cpu < maxCycles.size(); cpu++) { - maxCycles[cpu] = GetCpuCycles(cpu); + maxCycles[cpu] = oeaware::GetCpuCycles(cpu); sysMaxCycles += maxCycles[cpu]; } + + if (sysMaxCycles <= 0) { + std::cout << "use dmidecode to obtain cpu frequency" << std::endl; + sysMaxCycles = maxCpuFreqByDmi * maxCycles.size(); + } } bool Env::Init() @@ -64,6 +52,7 @@ bool Env::Init() } numaNum = numa_num_configured_nodes(); cpuNum = sysconf(_SC_NPROCESSORS_CONF); + maxCpuFreqByDmi = oeaware::GetCpuFreqByDmi(); cpu2Node.resize(cpuNum, -1); struct bitmask *cpumask = numa_allocate_cpumask(); for (int nid = 0; nid < numaNum; ++nid) { @@ -80,7 +69,11 @@ bool Env::Init() pageMask = GetPageMask(); InitDistance(); cpuMaxCycles.resize(cpuNum, 0); - InitCpuCycles(cpuMaxCycles, sysMaxCycles); + InitCpuCycles(cpuMaxCycles, sysMaxCycles, maxCpuFreqByDmi); + if (sysMaxCycles <= 0) { + std::cout << "failed to get sysMaxCycles" << std::endl; + return false; + } initialized = true; return true; } diff --git a/src/plugin/scenario/analysis/analysis/env.h b/src/plugin/scenario/analysis/analysis/env.h index f75f035..28b21f4 100644 --- a/src/plugin/scenario/analysis/analysis/env.h +++ b/src/plugin/scenario/analysis/analysis/env.h @@ -36,6 +36,7 @@ public: int cpuNum; unsigned long pageMask = 0; uint64_t sysMaxCycles = 0; + uint64_t maxCpuFreqByDmi; std::vector cpu2Node; std::vector> distance; std::vector cpuMaxCycles; // per second diff --git a/src/plugin/tune/docker/cpu_burst.cpp b/src/plugin/tune/docker/cpu_burst.cpp index 58b41dd..1e60fb9 100644 --- a/src/plugin/tune/docker/cpu_burst.cpp +++ b/src/plugin/tune/docker/cpu_burst.cpp @@ -14,6 +14,7 @@ #include #include #include "oeaware/data/pmu_counting_data.h" +#include "oeaware/utils.h" constexpr double NINETY_PERCENT = 0.9; constexpr int MILLISECONDS_IN_SECOND = 1000; @@ -35,34 +36,28 @@ static void SetCfsBurstUs(const std::string &id, int cfsBurstUs) return; } -static uint64_t GetCpuCycles(int cpu) +bool CpuBurst::Init() { - std::string freq_path = "/sys/devices/system/cpu/cpu" + std::to_string(cpu) + "/cpufreq/scaling_cur_freq"; - std::ifstream freq_file(freq_path); + curSysCycles = 0; + maxCpuFreqByDmi = oeaware::GetCpuFreqByDmi(); - if (!freq_file.is_open()) { - return 0; + cpuNum = sysconf(_SC_NPROCESSORS_CONF); + if (cpuNum <= 0) { + std::cout << "can not get cpu num" << std::endl; + return false; } - uint64_t freq; - freq_file >> freq; - freq_file.close(); - - if (freq_file.fail()) { - return 0; + for (unsigned int i = 0; i < cpuNum; i++) { + maxSysCycles += oeaware::GetCpuCycles(i); } - return freq * 1000; // 1000: kHz to Hz -} - -bool CpuBurst::Init() -{ - curSysCycles = 0; - cpuNum = sysconf(_SC_NPROCESSORS_CONF); - for (unsigned int i = 0; i < cpuNum; i++) { - maxSysCycles += GetCpuCycles(i); + if (maxSysCycles <= 0) { + std::cout << "use dmidecode to obtain cpu frequency" << std::endl; + maxSysCycles = maxCpuFreqByDmi * cpuNum; } - if (cpuNum <= 0 || maxSysCycles <= 0) { + + if (maxSysCycles <= 0) { + std::cout << "can not get cpu frequency" << std::endl; return false; } return true; diff --git a/src/plugin/tune/docker/cpu_burst.h b/src/plugin/tune/docker/cpu_burst.h index b485747..8ed7fae 100644 --- a/src/plugin/tune/docker/cpu_burst.h +++ b/src/plugin/tune/docker/cpu_burst.h @@ -49,6 +49,7 @@ private: unsigned int cpuNum = 0; uint64_t maxSysCycles = 0; // per second uint64_t curSysCycles = 0; + uint64_t maxCpuFreqByDmi; std::unordered_map containers; void UpdatePmu(const DataList &dataList); void UpdateDocker(const DataList &dataList); -- 2.33.0