sitara_depot/components/free_rtos/profiler/quick_profiler.hpp
2023-08-10 18:04:33 +03:00

115 lines
2.6 KiB
C++

/*
* quick_profiler.hpp
*
* Created on: Aug 10, 2023
* Author: algin
*/
#ifndef FREE_RTOS_PROFILER_QUICK_PROFILER_HPP_
#define FREE_RTOS_PROFILER_QUICK_PROFILER_HPP_
#include <cstdint>
#include <array>
#include <kernel/dpl/DebugP.h>
#include <kernel/dpl/CycleCounterP.h>
namespace free_rtos {
#define PROFILE(name, size, id) static free_rtos::QuickProfiler<size> name##_profiler{#name}; \
free_rtos::QuickProfilerItem<size> name##_profile_item_##id{name##_profiler}
#define CREATE_PROFILER(name, size) static free_rtos::QuickProfiler<size> name##_profiler{#name};
#define ADD_PROFILE_ITEM(name, size, id) free_rtos::QuickProfilerItem<size> name##_profile_item_##id{name##_profiler}
static void QuickProfiler_init(const uint64_t cpuFreqHz) {
CycleCounterP_init(cpuFreqHz);
CycleCounterP_reset();
uint64_t nsToTicks = CycleCounterP_nsToTicks(1000);
DebugP_log((char *)"%lld ticks in 1000 nanoseconds\r\n", nsToTicks);
}
template<size_t size>
class QuickProfiler {
public:
QuickProfiler(const char *name)
: name_{name} { };
void collect(uint32_t diff) {
uint32_t counter = counter_;
buffer_[counter] = diff;
counter++;
if(counter >= size) {
counter = 0;
dump();
}
counter_ = counter;
}
private:
const char *name_;
size_t counter_{0};
std::array<uint32_t, size> buffer_;
void dump() {
uint64_t average{0x0000000000000000};
uint32_t min{0xFFFFFFFF};
uint32_t max{0x00000000};
for(uint32_t value : buffer_) {
average += value;
if(value < min) {
min = value;
}
if(value > max) {
max = value;
}
}
average /= size;
DebugP_log((char *)"Profiler %s average: %lld min: %d max: %d\r\n", name_, average, min, max);
}
};
template<size_t size>
class QuickProfilerItem {
public:
QuickProfilerItem(QuickProfiler<size>& profiler)
: profiler_{profiler} {
start_cycle_ = CycleCounterP_getCount32();
};
~QuickProfilerItem() {
uint32_t end_cycle = CycleCounterP_getCount32();
uint32_t start_cycle = start_cycle_;
uint32_t diff;
if(end_cycle > start_cycle) {
diff = end_cycle - start_cycle;
} else {
diff = (0xFFFFFFFFU - start_cycle) + end_cycle;
}
profiler_.collect(diff);
}
private:
QuickProfiler<size>& profiler_;
uint32_t start_cycle_;
};
} // namespace free_rtos
#endif /* FREE_RTOS_PROFILER_QUICK_PROFILER_HPP_ */