PerformanceTracker.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. // Copyright 2022 Dolphin Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <array>
  5. #include <chrono>
  6. #include <fstream>
  7. #include <optional>
  8. #include <shared_mutex>
  9. #include "Common/CommonTypes.h"
  10. class PerformanceTracker
  11. {
  12. private:
  13. // Must be powers of 2 for masking to work
  14. static constexpr u64 MAX_DT_QUEUE_SIZE = 1UL << 12;
  15. static constexpr u64 MAX_QUALITY_GRAPH_SIZE = 1UL << 8;
  16. static inline std::size_t IncrementIndex(const std::size_t index)
  17. {
  18. return (index + 1) & (MAX_DT_QUEUE_SIZE - 1);
  19. }
  20. static inline std::size_t DecrementIndex(const std::size_t index)
  21. {
  22. return (index - 1) & (MAX_DT_QUEUE_SIZE - 1);
  23. }
  24. static inline std::size_t GetDifference(const std::size_t begin, const std::size_t end)
  25. {
  26. return (end - begin) & (MAX_DT_QUEUE_SIZE - 1);
  27. }
  28. public:
  29. PerformanceTracker(const std::optional<std::string> log_name = std::nullopt,
  30. const std::optional<s64> sample_window_us = std::nullopt);
  31. ~PerformanceTracker();
  32. PerformanceTracker(const PerformanceTracker&) = delete;
  33. PerformanceTracker& operator=(const PerformanceTracker&) = delete;
  34. PerformanceTracker(PerformanceTracker&&) = delete;
  35. PerformanceTracker& operator=(PerformanceTracker&&) = delete;
  36. // Functions for recording performance information
  37. void Reset();
  38. void Count();
  39. // Functions for reading performance information
  40. DT GetSampleWindow() const;
  41. double GetHzAvg() const;
  42. DT GetDtAvg() const;
  43. DT GetDtStd() const;
  44. DT GetLastRawDt() const;
  45. void ImPlotPlotLines(const char* label) const;
  46. private: // Functions for managing dt queue
  47. inline void QueueClear();
  48. inline void QueuePush(DT dt);
  49. inline const DT& QueuePop();
  50. inline const DT& QueueTop() const;
  51. inline const DT& QueueBottom() const;
  52. std::size_t inline QueueSize() const;
  53. bool inline QueueEmpty() const;
  54. // Handle pausing and logging
  55. void LogRenderTimeToFile(DT val);
  56. void SetPaused(bool paused);
  57. bool m_paused = false;
  58. int m_on_state_changed_handle;
  59. // Name of log file and file stream
  60. std::optional<std::string> m_log_name;
  61. std::ofstream m_bench_file;
  62. // Last time Count() was called
  63. TimePoint m_last_time;
  64. // Amount of time to sample dt's over (defaults to config)
  65. const std::optional<s64> m_sample_window_us;
  66. // Queue + Running Total used to calculate average dt
  67. DT m_dt_total = DT::zero();
  68. std::array<DT, MAX_DT_QUEUE_SIZE> m_dt_queue;
  69. std::size_t m_dt_queue_begin = 0;
  70. std::size_t m_dt_queue_end = 0;
  71. // Average rate/time throughout the window
  72. DT m_dt_avg = DT::zero(); // Uses Moving Average
  73. double m_hz_avg = 0.0; // Uses Moving Average + Euler Average
  74. // Used to initialize this on demand instead of on every Count()
  75. mutable std::optional<DT> m_dt_std = std::nullopt;
  76. // Used to enable thread safety with the performance tracker
  77. mutable std::shared_mutex m_mutex;
  78. };