dolphin/Source/Core/VideoCommon/PerformanceTracker.h
2023-01-06 20:27:25 +01:00

105 lines
2.8 KiB
C++

// Copyright 2022 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <array>
#include <chrono>
#include <fstream>
#include <optional>
#include <shared_mutex>
#include "Common/CommonTypes.h"
class PerformanceTracker
{
private:
// Must be powers of 2 for masking to work
static constexpr u64 MAX_DT_QUEUE_SIZE = 1UL << 12;
static constexpr u64 MAX_QUALITY_GRAPH_SIZE = 1UL << 8;
static inline std::size_t IncrementIndex(const std::size_t index)
{
return (index + 1) & (MAX_DT_QUEUE_SIZE - 1);
}
static inline std::size_t DecrementIndex(const std::size_t index)
{
return (index - 1) & (MAX_DT_QUEUE_SIZE - 1);
}
static inline std::size_t GetDifference(const std::size_t begin, const std::size_t end)
{
return (end - begin) & (MAX_DT_QUEUE_SIZE - 1);
}
public:
PerformanceTracker(const std::optional<std::string> log_name = std::nullopt,
const std::optional<s64> sample_window_us = std::nullopt);
~PerformanceTracker();
PerformanceTracker(const PerformanceTracker&) = delete;
PerformanceTracker& operator=(const PerformanceTracker&) = delete;
PerformanceTracker(PerformanceTracker&&) = delete;
PerformanceTracker& operator=(PerformanceTracker&&) = delete;
// Functions for recording performance information
void Reset();
void Count();
// Functions for reading performance information
DT GetSampleWindow() const;
double GetHzAvg() const;
DT GetDtAvg() const;
DT GetDtStd() const;
DT GetLastRawDt() const;
void ImPlotPlotLines(const char* label) const;
private: // Functions for managing dt queue
inline void QueueClear();
inline void QueuePush(DT dt);
inline const DT& QueuePop();
inline const DT& QueueTop() const;
inline const DT& QueueBottom() const;
std::size_t inline QueueSize() const;
bool inline QueueEmpty() const;
// Handle pausing and logging
void LogRenderTimeToFile(DT val);
void SetPaused(bool paused);
bool m_paused = false;
int m_on_state_changed_handle;
// Name of log file and file stream
std::optional<std::string> m_log_name;
std::ofstream m_bench_file;
// Last time Count() was called
TimePoint m_last_time;
// Amount of time to sample dt's over (defaults to config)
const std::optional<s64> m_sample_window_us;
// Queue + Running Total used to calculate average dt
DT m_dt_total = DT::zero();
std::array<DT, MAX_DT_QUEUE_SIZE> m_dt_queue;
std::size_t m_dt_queue_begin = 0;
std::size_t m_dt_queue_end = 0;
// Average rate/time throughout the window
DT m_dt_avg = DT::zero(); // Uses Moving Average
double m_hz_avg = 0.0; // Uses Moving Average + Euler Average
// Used to initialize this on demand instead of on every Count()
mutable std::optional<DT> m_dt_std = std::nullopt;
// Used to enable thread safety with the performance tracker
mutable std::shared_mutex m_mutex;
};