1
0
Fork 0

Codechange: TicToc can now accumulate and output every tick

pull/14323/head
glx22 2025-05-22 21:55:31 +02:00 committed by Loïc Guilloux
parent fca75fd06a
commit 4beb23af30
2 changed files with 48 additions and 7 deletions

View File

@ -61,20 +61,49 @@ void SetDebugString(std::string_view s, SetDebugStringErrorFunc error_func);
std::string GetDebugString();
/** TicToc profiling.
* Usage:
* Usage for max_count based output:
* static TicToc::State state("A name", 1);
* TicToc tt(state);
* --Do your code--
*
* Usage for per-tick output:
* static TicToc::State state("A name");
* TicToc tt(state);
* --Do your code--
*/
struct TicToc {
/** Persistent state for TicToc profiling. */
struct State {
const std::string_view name;
const uint32_t max_count;
const std::optional<uint32_t> max_count;
uint32_t count = 0;
uint64_t chrono_sum = 0;
constexpr State(std::string_view name, uint32_t max_count) : name(name), max_count(max_count) { }
using States = std::vector<State *>;
State(std::string_view name, std::optional<uint32_t> max_count = {}) : name(name), max_count(max_count)
{
GetStates().push_back(this);
}
~State()
{
/* Container might be already destroyed. */
if (!GetStates().empty()) std::erase(GetStates(), this);
}
static States &GetStates()
{
thread_local static States s_states;
return s_states;
}
void OutputAndReset(const std::string_view prefix = "")
{
Debug(misc, 0, "[{}] [{}] {} calls in {} us [avg: {:.1f} us]", prefix, this->name, this->count, this->chrono_sum, this->chrono_sum / static_cast<double>(this->count));
this->count = 0;
this->chrono_sum = 0;
}
};
State &state;
@ -85,10 +114,17 @@ struct TicToc {
inline ~TicToc()
{
this->state.chrono_sum += (std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock::now() - this->chrono_start)).count();
if (++this->state.count == this->state.max_count) {
Debug(misc, 0, "[{}] {} us [avg: {:.1f} us]", this->state.name, this->state.chrono_sum, this->state.chrono_sum / static_cast<double>(this->state.count));
this->state.count = 0;
this->state.chrono_sum = 0;
this->state.count++;
if (this->state.max_count.has_value() && this->state.count == this->state.max_count.value()) {
this->state.OutputAndReset("MaxCount");
}
}
static void Tick(const std::string_view prefix)
{
for (auto state : State::GetStates()) {
if (state->max_count.has_value() || state->count == 0) continue;
state->OutputAndReset(prefix);
}
}
};

View File

@ -10,6 +10,7 @@
#ifndef VIDEO_VIDEO_DRIVER_HPP
#define VIDEO_VIDEO_DRIVER_HPP
#include "../debug.h"
#include "../driver.h"
#include "../core/geometry_type.hpp"
#include "../core/math_func.hpp"
@ -318,6 +319,8 @@ protected:
if (_ddc_fastforward) return std::chrono::microseconds(0);
#endif /* DEBUG_DUMP_COMMANDS */
TicToc::Tick("GameTick");
/* If we are paused, run on normal speed. */
if (_pause_mode.Any()) return std::chrono::milliseconds(MILLISECONDS_PER_TICK);
/* Infinite speed, as quickly as you can. */
@ -328,6 +331,8 @@ protected:
std::chrono::steady_clock::duration GetDrawInterval()
{
TicToc::Tick("DrawTick");
/* If vsync, draw interval is decided by the display driver */
if (_video_vsync && this->uses_hardware_acceleration) return std::chrono::microseconds(0);
return std::chrono::microseconds(1000000 / _settings_client.gui.refresh_rate);