168 lines
5.3 KiB
C++
168 lines
5.3 KiB
C++
#pragma once
|
|
/*
|
|
* Created by Brett on 20/09/23.
|
|
* Licensed under GNU General Public License V3.0
|
|
* See LICENSE file for license detail
|
|
*/
|
|
|
|
#ifndef BLT_PROFILER_V2_H
|
|
#define BLT_PROFILER_V2_H
|
|
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <vector>
|
|
#include <blt/std/logging.h>
|
|
|
|
namespace blt
|
|
{
|
|
// use the historical values (average) instead of the latest values
|
|
static inline constexpr std::uint32_t PRINT_HISTORY = 0x1;
|
|
// print out the cycles
|
|
static inline constexpr std::uint32_t PRINT_CYCLES = 0x2;
|
|
// print out the wall time
|
|
static inline constexpr std::uint32_t PRINT_WALL = 0x4;
|
|
// print out the thread CPU time
|
|
static inline constexpr std::uint32_t PRINT_THREAD = 0x8;
|
|
|
|
enum class sort_by
|
|
{
|
|
CYCLES,
|
|
WALL,
|
|
THREAD
|
|
};
|
|
|
|
// 32 bit currently not supported
|
|
typedef std::int64_t pf_time_t;
|
|
typedef std::uint64_t pf_cycle_t;
|
|
|
|
struct interval_t
|
|
{
|
|
pf_time_t wall_start = 0;
|
|
pf_time_t wall_end = 0;
|
|
pf_time_t wall_total = 0;
|
|
|
|
pf_time_t thread_start = 0;
|
|
pf_time_t thread_end = 0;
|
|
pf_time_t thread_total = 0;
|
|
|
|
pf_cycle_t cycles_start = 0;
|
|
pf_cycle_t cycles_end = 0;
|
|
pf_cycle_t cycles_total = 0;
|
|
|
|
std::uint64_t count = 0;
|
|
std::string interval_name;
|
|
};
|
|
|
|
struct cycle_interval_t
|
|
{
|
|
pf_cycle_t cycles_start = 0;
|
|
pf_cycle_t cycles_end = 0;
|
|
pf_cycle_t cycles_total = 0;
|
|
std::uint64_t count = 0;
|
|
std::string interval_name;
|
|
};
|
|
|
|
struct profile_t
|
|
{
|
|
std::vector<interval_t*> intervals;
|
|
std::vector<cycle_interval_t*> cycle_intervals;
|
|
std::string name;
|
|
|
|
explicit profile_t(std::string name): name(std::move(name))
|
|
{}
|
|
|
|
profile_t(const profile_t& p) = delete;
|
|
|
|
profile_t& operator=(const profile_t& p) = delete;
|
|
|
|
~profile_t();
|
|
};
|
|
|
|
interval_t* createInterval(profile_t& profiler, std::string interval_name);
|
|
|
|
void startInterval(interval_t* interval);
|
|
|
|
inline interval_t* startInterval(profile_t& profiler, std::string interval_name){
|
|
auto* p = createInterval(profiler, std::move(interval_name));
|
|
startInterval(p);
|
|
return p;
|
|
}
|
|
|
|
void endInterval(interval_t* interval);
|
|
|
|
void printProfile(profile_t& profiler, std::uint32_t flags = PRINT_HISTORY | PRINT_CYCLES | PRINT_THREAD | PRINT_WALL,
|
|
sort_by sort = sort_by::CYCLES, blt::logging::log_level log_level = blt::logging::log_level::NONE);
|
|
|
|
void writeProfile(std::ifstream& stream, const profile_t& profiler);
|
|
|
|
void clearProfile(profile_t& profiler);
|
|
|
|
namespace _internal
|
|
{
|
|
void startInterval(const std::string& profile_name, const std::string& interval_name);
|
|
|
|
void endInterval(const std::string& profile_name, const std::string& interval_name);
|
|
|
|
void printProfile(const std::string& profile_name, std::uint32_t flags = PRINT_HISTORY | PRINT_CYCLES | PRINT_THREAD | PRINT_WALL,
|
|
sort_by sort = sort_by::CYCLES, blt::logging::log_level log_level = blt::logging::log_level::NONE);
|
|
|
|
void writeProfile(std::ifstream& stream, const std::string& profile_name);
|
|
}
|
|
|
|
class auto_interval
|
|
{
|
|
private:
|
|
interval_t* iv;
|
|
public:
|
|
auto_interval(std::string interval_name, profile_t& profiler)
|
|
{
|
|
iv = blt::createInterval(profiler, std::move(interval_name));
|
|
blt::startInterval(iv);
|
|
}
|
|
|
|
explicit auto_interval(interval_t* iv): iv(iv)
|
|
{
|
|
blt::startInterval(iv);
|
|
}
|
|
|
|
auto_interval(const auto_interval& i) = delete;
|
|
|
|
auto_interval& operator=(const auto_interval& i) = delete;
|
|
|
|
~auto_interval()
|
|
{
|
|
blt::endInterval(iv);
|
|
}
|
|
};
|
|
|
|
}
|
|
|
|
#ifdef BLT_DISABLE_PROFILING
|
|
#define BLT_START_INTERVAL(profileName, intervalName)
|
|
#define BLT_END_INTERVAL(profileName, intervalName)
|
|
#define BLT_PRINT_PROFILE(profileName, ...)
|
|
#define BLT_WRITE_PROFILE(stream, profileName)
|
|
#else
|
|
/**
|
|
* Starts an interval to be measured, when ended the row will be added to the specified profile.
|
|
*/
|
|
#define BLT_START_INTERVAL(profileName, intervalName) blt::_internal::startInterval(profileName, intervalName)
|
|
/**
|
|
* Ends an interval, adds the interval to the profile.
|
|
*/
|
|
#define BLT_END_INTERVAL(profileName, intervalName) blt::_internal::endInterval(profileName, intervalName)
|
|
/**
|
|
* Prints the profile order from least time to most time.
|
|
* @param profileName the profile to print
|
|
* @param loggingLevel blt::logging::LOG_LEVEL to log with (default: BLT_NONE)
|
|
* @param averageHistory use the historical collection of interval rows in an average or just the latest? (default: false)
|
|
*/
|
|
#define BLT_PRINT_PROFILE(profileName, ...) blt::_internal::printProfile(profileName, ##__VA_ARGS__)
|
|
/**
|
|
* writes the profile to an output stream, ordered from least time to most time, in CSV format.
|
|
*/
|
|
#define BLT_WRITE_PROFILE(stream, profileName) blt::_internal::writeProfile(stream, profileName)
|
|
#endif
|
|
|
|
#endif //BLT_PROFILER_V2_H
|