From e2da7ee5e9732ec0d1962b7d74737b8ef5463a9e Mon Sep 17 00:00:00 2001 From: Kshitij Sisodia Date: Mon, 14 Feb 2022 11:22:58 +0000 Subject: MLECO-2970: Moving Profiler out as a CMake target. Profiler is a stand alone static lib that will depend on log and hal targets. Change-Id: Ibbff289c6760982f54ae278d95a054e73db018c8 --- source/application/profiler/Profiler.cc | 281 ----------------------- source/application/profiler/include/Profiler.hpp | 135 ----------- 2 files changed, 416 deletions(-) delete mode 100644 source/application/profiler/Profiler.cc delete mode 100644 source/application/profiler/include/Profiler.hpp (limited to 'source/application') diff --git a/source/application/profiler/Profiler.cc b/source/application/profiler/Profiler.cc deleted file mode 100644 index efbc64d..0000000 --- a/source/application/profiler/Profiler.cc +++ /dev/null @@ -1,281 +0,0 @@ -/* - * Copyright (c) 2022 Arm Limited. All rights reserved. - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "Profiler.hpp" -#include "log_macros.h" - -#include - -namespace arm { -namespace app { - Profiler::Profiler(hal_platform* platform, const char* name = "Unknown") - : m_name(name) - { - if (platform && platform->inited) { - this->m_pPlatform = platform; - this->Reset(); - } else { - printf_err("Profiler %s initialised with invalid platform\n", - this->m_name.c_str()); - } - } - - bool Profiler::StartProfiling(const char* name) - { - if (name) { - this->SetName(name); - } - if (this->m_pPlatform && !this->m_started) { - this->m_pPlatform->timer->reset(); - this->m_tstampSt = this->m_pPlatform->timer->start_profiling(); - this->m_started = true; - return true; - } - printf_err("Failed to start profiler %s\n", this->m_name.c_str()); - return false; - } - - bool Profiler::StopProfiling() - { - if (this->m_pPlatform && this->m_started) { - this->m_tstampEnd = this->m_pPlatform->timer->stop_profiling(); - this->m_started = false; - - this->AddProfilingUnit(this->m_tstampSt, this->m_tstampEnd, this->m_name); - - return true; - } - printf_err("Failed to stop profiler %s\n", this->m_name.c_str()); - return false; - } - - bool Profiler::StopProfilingAndReset() - { - if (this->StopProfiling()) { - this->Reset(); - return true; - } - printf_err("Failed to stop profiler %s\n", this->m_name.c_str()); - return false; - } - - void Profiler::Reset() - { - this->m_started = false; - this->m_series.clear(); - memset(&this->m_tstampSt, 0, sizeof(this->m_tstampSt)); - memset(&this->m_tstampEnd, 0, sizeof(this->m_tstampEnd)); - } - - void calcProfilingStat(uint64_t currentValue, - Statistics& data, - uint32_t samples) - { - data.total += currentValue; - data.min = std::min(data.min, currentValue); - data.max = std::max(data.max, currentValue); - data.avrg = ((double)data.total / samples); - } - - void Profiler::GetAllResultsAndReset(std::vector& results) - { - for (const auto& item: this->m_series) { - auto name = item.first; - ProfilingSeries series = item.second; - ProfileResult result{}; - result.name = item.first; - result.samplesNum = series.size(); - - Statistics AXI0_RD { - .name = "NPU AXI0_RD_DATA_BEAT_RECEIVED", - .unit = "beats", - .total = 0, - .avrg = 0.0, - .min = series[0].axi0writes, - .max = 0 - }; - Statistics AXI0_WR { - .name = "NPU AXI0_WR_DATA_BEAT_WRITTEN", - .unit = "beats", - .total = 0, - .avrg = 0.0, - .min = series[0].axi0reads, - .max = 0 - }; - Statistics AXI1_RD { - .name = "NPU AXI1_RD_DATA_BEAT_RECEIVED", - .unit = "beats", - .total = 0, - .avrg = 0.0, - .min = series[0].axi1reads, - .max = 0 - }; - Statistics NPU_ACTIVE { - .name = "NPU ACTIVE", - .unit = "cycles", - .total = 0, - .avrg = 0.0, - .min = series[0].activeNpuCycles, - .max = 0 - }; - Statistics NPU_IDLE { - .name = "NPU IDLE", - .unit = "cycles", - .total = 0, - .avrg = 0.0, - .min = series[0].idleNpuCycles, - .max = 0 - }; - Statistics NPU_Total { - .name = "NPU TOTAL", - .unit = "cycles", - .total = 0, - .avrg = 0.0, - .min = series[0].npuCycles, - .max = 0, - }; -#if defined(CPU_PROFILE_ENABLED) - Statistics CPU_ACTIVE { - .name = "CPU ACTIVE", - .unit = "cycles (approx)", - .total = 0, - .avrg = 0.0, - .min = series[0].cpuCycles - NPU_ACTIVE.min, - .max = 0 - }; - Statistics TIME { - .name = "Time", - .unit = "ms", - .total = 0, - .avrg = 0.0, - .min = static_cast(series[0].time), - .max = 0 - }; -#endif - for(ProfilingUnit& unit: series){ - - calcProfilingStat(unit.npuCycles, - NPU_Total, result.samplesNum); - - calcProfilingStat(unit.activeNpuCycles, - NPU_ACTIVE, result.samplesNum); - - calcProfilingStat(unit.idleNpuCycles, - NPU_IDLE, result.samplesNum); - - calcProfilingStat(unit.axi0writes, - AXI0_WR, result.samplesNum); - - calcProfilingStat(unit.axi0reads, - AXI0_RD, result.samplesNum); - - calcProfilingStat(unit.axi1reads, - AXI1_RD, result.samplesNum); -#if defined(CPU_PROFILE_ENABLED) - calcProfilingStat(static_cast(unit.time), - TIME, result.samplesNum); - - calcProfilingStat(unit.cpuCycles - unit.activeNpuCycles, - CPU_ACTIVE, result.samplesNum); -#endif - } - result.data.emplace_back(AXI0_RD); - result.data.emplace_back(AXI0_WR); - result.data.emplace_back(AXI1_RD); - result.data.emplace_back(NPU_ACTIVE); - result.data.emplace_back(NPU_IDLE); - result.data.emplace_back(NPU_Total); -#if defined(CPU_PROFILE_ENABLED) - result.data.emplace_back(CPU_ACTIVE); - result.data.emplace_back(TIME); -#endif - results.emplace_back(result); - } - this->Reset(); - } - - void printStatisticsHeader(uint32_t samplesNum) { - info("Number of samples: %" PRIu32 "\n", samplesNum); - info("%s\n", "Total / Avg./ Min / Max"); - } - - void Profiler::PrintProfilingResult(bool printFullStat) { - std::vector results{}; - GetAllResultsAndReset(results); - for(ProfileResult& result: results) { - info("Profile for %s:\n", result.name.c_str()); - - if (printFullStat) { - printStatisticsHeader(result.samplesNum); - } - - for (Statistics &stat: result.data) { - if (printFullStat) { - info("%s %s: %" PRIu64 "/ %.0f / %" PRIu64 " / %" PRIu64 " \n", - stat.name.c_str(), stat.unit.c_str(), - stat.total, stat.avrg, stat.min, stat.max); - } else { - info("%s %s: %.0f\n", stat.name.c_str(), stat.unit.c_str(), stat.avrg); - } - } - } - } - - void Profiler::SetName(const char* str) - { - this->m_name = std::string(str); - } - - void Profiler::AddProfilingUnit(time_counter start, time_counter end, - const std::string& name) - { - if (!this->m_pPlatform) { - printf_err("Invalid platform\n"); - return; - } - - platform_timer * timer = this->m_pPlatform->timer; - - struct ProfilingUnit unit; - - if (timer->cap.npu_cycles && timer->get_npu_cycles_diff) - { - const size_t size = 6; - uint64_t pmuCounters[size] = {0}; - /* 6 values: total cc, active cc, idle cc, axi0 read, axi0 write, axi1 read*/ - if (0 == timer->get_npu_cycles_diff(&start, &end, pmuCounters, size)) { - unit.npuCycles = pmuCounters[0]; - unit.activeNpuCycles = pmuCounters[1]; - unit.idleNpuCycles = pmuCounters[2]; - unit.axi0reads = pmuCounters[3]; - unit.axi0writes = pmuCounters[4]; - unit.axi1reads = pmuCounters[5]; - } - } - - if (timer->cap.cpu_cycles && timer->get_cpu_cycle_diff) { - unit.cpuCycles = timer->get_cpu_cycle_diff(&start, &end); - } - - if (timer->cap.duration_ms && timer->get_duration_ms) { - unit.time = timer->get_duration_ms(&start, &end); - } - - this->m_series[name].emplace_back(unit); - } - -} /* namespace app */ -} /* namespace arm */ diff --git a/source/application/profiler/include/Profiler.hpp b/source/application/profiler/include/Profiler.hpp deleted file mode 100644 index 503d805..0000000 --- a/source/application/profiler/include/Profiler.hpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2022 Arm Limited. All rights reserved. - * SPDX-License-Identifier: Apache-2.0 - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef APP_PROFILER_HPP -#define APP_PROFILER_HPP - -#include "hal.h" - -#include -#include -#include - -namespace arm { -namespace app { - - /** Statistics for a profiling metric. */ - struct Statistics { - std::string name; - std::string unit; - std::uint64_t total; - double avrg; - std::uint64_t min; - std::uint64_t max; - }; - - /** Profiling results with calculated statistics. */ - struct ProfileResult { - std::string name; - std::uint32_t samplesNum; - std::vector data; - }; - - /** A single profiling unit definition. */ - struct ProfilingUnit { - uint64_t npuCycles = 0; - uint64_t activeNpuCycles = 0; - uint64_t idleNpuCycles = 0; - uint64_t axi0writes = 0; - uint64_t axi0reads = 0; - uint64_t axi1reads = 0; - uint64_t cpuCycles = 0; - time_t time = 0; - }; - - /* A collection of profiling units. */ - using ProfilingSeries = std::vector; - - /* A map for string identifiable profiling series. */ - using ProfilingMap = std::map; - - /** - * @brief A very simple profiler example using the platform timer - * implementation. - */ - class Profiler { - public: - /** - * @brief Constructor for profiler. - * @param[in] platform Pointer to a valid, initialised hal platform. - * @param[in] name A friendly name for this profiler. - **/ - Profiler(hal_platform* platform, const char* name); - - /** Block the default constructor. */ - Profiler() = delete; - - /** Default destructor. */ - ~Profiler() = default; - - /** @brief Start profiling => get starting time-stamp. */ - bool StartProfiling(const char* name = nullptr); - - /** @brief Stop profiling => get the ending time-stamp. */ - bool StopProfiling(); - - /** @brief Stops the profiling and internally resets the - * platform timers. */ - bool StopProfilingAndReset(); - - /** @brief Reset the platform timers. */ - void Reset(); - - /** - * @brief Collects profiling results statistics and resets the profiler. - **/ - void GetAllResultsAndReset(std::vector& results); - - /** - * @brief Prints collected profiling results and resets the profiler. - **/ - void PrintProfilingResult(bool printFullStat = false); - - /** @brief Set the profiler name. */ - void SetName(const char* str); - - private: - ProfilingMap m_series; /* Profiling series map. */ - time_counter m_tstampSt{}; /* Container for a current starting timestamp. */ - time_counter m_tstampEnd{}; /* Container for a current ending timestamp. */ - hal_platform * m_pPlatform = nullptr; /* Platform pointer - to get the timer. */ - - bool m_started = false; /* Indicates profiler has been started. */ - - std::string m_name; /* Name given to this profiler. */ - - /** - * @brief Appends the profiling unit computed by the "start" and - * "end" timestamps to the profiling series identified by - * the name provided. - * @param[in] start Starting time-stamp. - * @param[in] end Ending time-stamp. - * @param[in] name Name for the profiling unit series to be - * appended to. - **/ - void AddProfilingUnit(time_counter start, time_counter end, - const std::string& name); - }; - -} /* namespace app */ -} /* namespace arm */ - -#endif /* APP_PROFILER_HPP */ -- cgit v1.2.1