Compare commits

...

5 Commits

Author SHA1 Message Date
Brett 2a5d643285 minor cleanup 2023-10-05 01:55:15 -04:00
Brett 9c712402f3 profiler_v2 seems to be completely functional 2023-10-05 01:48:54 -04:00
Brett ab24a8733b add partial API compatability with profiler v1
the general idea is the same however due to how profiles are handled after calling write or print profile the intervals inside are no longer valid.
(they are deleted and will be removed from the internal hashmap)
print profile is also now consistent with the new API, old calls will need to be updated.
2023-10-05 01:40:36 -04:00
Brett 3266a7b102 fix profiler disable macro 2023-10-05 01:31:54 -04:00
Brett 620c8b9e33 auto_interval, formatting see details for information
auto_interval now accepts an interval_t* which must be created manually. allows for clean RAII
format now switches to seconds after 1000ms instead of after 100ms. This feels more natural
2023-10-05 01:18:47 -04:00
3 changed files with 99 additions and 16 deletions

View File

@ -88,8 +88,8 @@ namespace blt::profiling {
#define BLT_START_INTERVAL(profileName, intervalName) #define BLT_START_INTERVAL(profileName, intervalName)
#define BLT_END_INTERVAL(profileName, intervalName) #define BLT_END_INTERVAL(profileName, intervalName)
#define BLT_POINT(profileName, pointName) #define BLT_POINT(profileName, pointName)
#define BLT_PRINT_ORDERED(profileName, ...) #define BLT_PRINT_PROFILE(profileName, ...)
#define BLT_WRITE_ORDERED(profileName, ...) #define BLT_WRITE_PROFILE(stream, profileName)
#else #else
/** /**
* Starts an interval to be measured, when ended the row will be added to the specified profile. * Starts an interval to be measured, when ended the row will be added to the specified profile.

View File

@ -11,7 +11,6 @@
#include <cstdint> #include <cstdint>
#include <string> #include <string>
#include <vector> #include <vector>
#include <blt/std/hashmap.h>
#include <blt/std/logging.h> #include <blt/std/logging.h>
namespace blt namespace blt
@ -80,8 +79,15 @@ namespace blt
}; };
interval_t* createInterval(profile_t& profiler, std::string interval_name); interval_t* createInterval(profile_t& profiler, std::string interval_name);
void startInterval(interval_t* interval); 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 endInterval(interval_t* interval);
void printProfile(profile_t& profiler, std::uint32_t flags = PRINT_HISTORY | PRINT_CYCLES | PRINT_THREAD | PRINT_WALL, void printProfile(profile_t& profiler, std::uint32_t flags = PRINT_HISTORY | PRINT_CYCLES | PRINT_THREAD | PRINT_WALL,
@ -97,9 +103,10 @@ namespace blt
void endInterval(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); 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(const std::string& profile_name); void writeProfile(std::ifstream& stream, const std::string& profile_name);
} }
class auto_interval class auto_interval
@ -113,6 +120,11 @@ namespace blt
blt::startInterval(iv); blt::startInterval(iv);
} }
explicit auto_interval(interval_t* iv): iv(iv)
{
blt::startInterval(iv);
}
auto_interval(const auto_interval& i) = delete; auto_interval(const auto_interval& i) = delete;
auto_interval& operator=(const auto_interval& i) = delete; auto_interval& operator=(const auto_interval& i) = delete;
@ -125,4 +137,31 @@ namespace blt
} }
#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 #endif //BLT_PROFILER_V2_H

View File

@ -8,10 +8,16 @@
#include <blt/std/system.h> #include <blt/std/system.h>
#include <blt/std/format.h> #include <blt/std/format.h>
#include <functional> #include <functional>
#include <blt/std/hashmap.h>
namespace blt namespace blt
{ {
/**
* General profiler functions
* --------------------------
*/
#define SORT_INTERVALS_FUNC_MACRO(use_history, TYPE_END, TYPE_START, TYPE_TOTAL) \ #define SORT_INTERVALS_FUNC_MACRO(use_history, TYPE_END, TYPE_START, TYPE_TOTAL) \
[&use_history](const interval_t* a, const interval_t* b) -> bool { \ [&use_history](const interval_t* a, const interval_t* b) -> bool { \
if (use_history){ \ if (use_history){ \
@ -99,15 +105,12 @@ namespace blt
switch (sort) switch (sort)
{ {
case sort_by::CYCLES: case sort_by::CYCLES:
BLT_DEBUG("Cycles");
sort_func = SORT_INTERVALS_FUNC_MACRO(use_history, cycles_start, cycles_end, cycles_total); sort_func = SORT_INTERVALS_FUNC_MACRO(use_history, cycles_start, cycles_end, cycles_total);
break; break;
case sort_by::WALL: case sort_by::WALL:
BLT_TRACE("WaLL");
sort_func = SORT_INTERVALS_FUNC_MACRO(use_history, wall_start, wall_end, wall_total); sort_func = SORT_INTERVALS_FUNC_MACRO(use_history, wall_start, wall_end, wall_total);
break; break;
case sort_by::THREAD: case sort_by::THREAD:
BLT_INFO("Thread!");
sort_func = SORT_INTERVALS_FUNC_MACRO(use_history, thread_start, thread_end, thread_total); sort_func = SORT_INTERVALS_FUNC_MACRO(use_history, thread_start, thread_end, thread_total);
break; break;
} }
@ -127,14 +130,14 @@ namespace blt
// we want to use the largest unit possible to keep the numbers small // we want to use the largest unit possible to keep the numbers small
// we might run into a case where something took 1000ns but other thing took 100s // we might run into a case where something took 1000ns but other thing took 100s
// which would be hard to deal with either way. So TODO // which would be hard to deal with either way. So TODO
if (wall > 1e5 && wall <= 1e8 && container.wall == unit::NS) if (wall > 1e6 && wall < 1e9 && container.wall == unit::NS)
container.wall = unit::MS; container.wall = unit::MS;
else if (wall > 1e8) else if (wall > 1e9)
container.wall = unit::S; container.wall = unit::S;
if (thread > 1e5 && thread <= 1e8 && container.thread == unit::NS) if (thread > 1e6 && thread < 1e9 && container.thread == unit::NS)
container.thread = unit::MS; container.thread = unit::MS;
else if (thread > 1e8) else if (thread > 1e9)
container.thread = unit::S; container.thread = unit::S;
return container; return container;
} }
@ -199,9 +202,50 @@ namespace blt
profile_t::~profile_t() profile_t::~profile_t()
{ {
for (auto* p : intervals) blt::clearProfile(*this);
delete p; }
for (auto* p : cycle_intervals)
delete p; /**
* profiler V1 partial backwards compat
* ----------------------------
*/
HASHMAP<std::string, HASHMAP<std::string, interval_t*>> profiles;
void _internal::startInterval(const std::string& profile_name, const std::string& interval_name)
{
auto& profile = profiles[profile_name];
if (!profile.contains(interval_name))
{
auto interval = new interval_t();
interval->interval_name = interval_name;
profile[interval_name] = interval;
}
blt::startInterval(profile[interval_name]);
}
void _internal::endInterval(const std::string& profile_name, const std::string& interval_name)
{
blt::endInterval(profiles[profile_name].at(interval_name));
}
void _internal::writeProfile(std::ifstream& stream, const std::string& profile_name)
{
auto& pref = profiles[profile_name];
profile_t profile{profile_name};
for (const auto& i : pref)
profile.intervals.push_back(i.second);
blt::writeProfile(stream, profile);
profiles.erase(profile_name);
}
void _internal::printProfile(const std::string& profile_name, std::uint32_t flags, sort_by sort, blt::logging::log_level log_level)
{
auto& pref = profiles[profile_name];
profile_t profile{profile_name};
for (const auto& i : pref)
profile.intervals.push_back(i.second);
blt::printProfile(profile, flags, sort, log_level);
profiles.erase(profile_name);
} }
} }