209 lines
6.0 KiB
C++
209 lines
6.0 KiB
C++
#ifndef YAZE_APP_GFX_PERFORMANCE_PROFILER_H
|
|
#define YAZE_APP_GFX_PERFORMANCE_PROFILER_H
|
|
|
|
#include <chrono>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
#include <SDL.h>
|
|
|
|
namespace yaze {
|
|
namespace gfx {
|
|
|
|
/**
|
|
* @brief Unified performance profiler for all YAZE operations
|
|
*
|
|
* The PerformanceProfiler class provides comprehensive timing and performance
|
|
* measurement capabilities for the entire YAZE application. It tracks operation
|
|
* times, calculates statistics, provides detailed performance reports, and integrates
|
|
* with the memory pool for efficient data storage.
|
|
*
|
|
* Key Features:
|
|
* - High-resolution timing for microsecond precision
|
|
* - Automatic statistics calculation (min, max, average, median)
|
|
* - Operation grouping and categorization
|
|
* - Memory usage tracking with MemoryPool integration
|
|
* - Performance regression detection
|
|
* - Enable/disable functionality for zero-overhead when disabled
|
|
* - Unified interface for both core and graphics operations
|
|
*
|
|
* Performance Optimizations:
|
|
* - Memory pool allocation for reduced fragmentation
|
|
* - Minimal overhead timing measurements
|
|
* - Efficient data structures for fast lookups
|
|
* - Configurable sampling rates
|
|
* - Automatic cleanup of old measurements
|
|
*
|
|
* Usage Examples:
|
|
* - Measure ROM loading performance
|
|
* - Track graphics operation efficiency
|
|
* - Monitor memory usage patterns
|
|
* - Detect performance regressions
|
|
*/
|
|
class PerformanceProfiler {
|
|
public:
|
|
static PerformanceProfiler& Get();
|
|
|
|
/**
|
|
* @brief Enable or disable performance monitoring
|
|
*
|
|
* When disabled, ScopedTimer operations become no-ops for better performance
|
|
* in production builds or when monitoring is not needed.
|
|
*/
|
|
static void SetEnabled(bool enabled) {
|
|
Get().enabled_ = enabled;
|
|
}
|
|
|
|
/**
|
|
* @brief Check if performance monitoring is enabled
|
|
*/
|
|
static bool IsEnabled() {
|
|
return Get().enabled_;
|
|
}
|
|
|
|
/**
|
|
* @brief Check if the profiler is in a valid state (not shutting down)
|
|
* This prevents crashes during static destruction order issues
|
|
*/
|
|
static bool IsValid() {
|
|
return !Get().is_shutting_down_;
|
|
}
|
|
|
|
/**
|
|
* @brief Start timing an operation
|
|
* @param operation_name Name of the operation to time
|
|
* @note Multiple operations can be timed simultaneously
|
|
*/
|
|
void StartTimer(const std::string& operation_name);
|
|
|
|
/**
|
|
* @brief End timing an operation
|
|
* @param operation_name Name of the operation to end timing
|
|
* @note Must match a previously started timer
|
|
*/
|
|
void EndTimer(const std::string& operation_name);
|
|
|
|
/**
|
|
* @brief Get timing statistics for an operation
|
|
* @param operation_name Name of the operation
|
|
* @return Statistics struct with timing data
|
|
*/
|
|
struct TimingStats {
|
|
double min_time_us = 0.0;
|
|
double max_time_us = 0.0;
|
|
double avg_time_us = 0.0;
|
|
double median_time_us = 0.0;
|
|
double total_time_ms = 0.0;
|
|
size_t sample_count = 0;
|
|
};
|
|
|
|
TimingStats GetStats(const std::string& operation_name) const;
|
|
|
|
/**
|
|
* @brief Generate a comprehensive performance report
|
|
* @param log_to_sdl Whether to log results to SDL_Log
|
|
* @return Formatted performance report string
|
|
*/
|
|
std::string GenerateReport(bool log_to_sdl = true) const;
|
|
|
|
/**
|
|
* @brief Clear all timing data
|
|
*/
|
|
void Clear();
|
|
|
|
/**
|
|
* @brief Clear timing data for a specific operation
|
|
* @param operation_name Name of the operation to clear
|
|
*/
|
|
void ClearOperation(const std::string& operation_name);
|
|
|
|
/**
|
|
* @brief Get list of all tracked operations
|
|
* @return Vector of operation names
|
|
*/
|
|
std::vector<std::string> GetOperationNames() const;
|
|
|
|
/**
|
|
* @brief Check if an operation is currently being timed
|
|
* @param operation_name Name of the operation to check
|
|
* @return True if operation is being timed
|
|
*/
|
|
bool IsTiming(const std::string& operation_name) const;
|
|
|
|
/**
|
|
* @brief Get the average time for an operation in milliseconds
|
|
* @param operation_name Name of the operation
|
|
* @return Average time in milliseconds
|
|
*/
|
|
double GetAverageTime(const std::string& operation_name) const;
|
|
|
|
/**
|
|
* @brief Get the total time for an operation in milliseconds
|
|
* @param operation_name Name of the operation
|
|
* @return Total time in milliseconds
|
|
*/
|
|
double GetTotalTime(const std::string& operation_name) const;
|
|
|
|
/**
|
|
* @brief Get the number of times an operation was measured
|
|
* @param operation_name Name of the operation
|
|
* @return Number of measurements
|
|
*/
|
|
int GetOperationCount(const std::string& operation_name) const;
|
|
|
|
/**
|
|
* @brief Print a summary of all operations to console
|
|
*/
|
|
void PrintSummary() const;
|
|
|
|
private:
|
|
PerformanceProfiler();
|
|
|
|
using TimePoint = std::chrono::high_resolution_clock::time_point;
|
|
using Duration = std::chrono::microseconds;
|
|
|
|
std::unordered_map<std::string, TimePoint> active_timers_;
|
|
std::unordered_map<std::string, std::vector<double>> operation_times_;
|
|
std::unordered_map<std::string, double> operation_totals_; // Total time per operation
|
|
std::unordered_map<std::string, int> operation_counts_; // Count per operation
|
|
|
|
bool enabled_ = true; // Performance monitoring enabled by default
|
|
bool is_shutting_down_ = false; // Flag to prevent operations during destruction
|
|
|
|
/**
|
|
* @brief Calculate median value from a sorted vector
|
|
* @param values Sorted vector of values
|
|
* @return Median value
|
|
*/
|
|
static double CalculateMedian(std::vector<double> values);
|
|
};
|
|
|
|
/**
|
|
* @brief RAII timer for automatic timing management
|
|
*
|
|
* Usage:
|
|
* {
|
|
* ScopedTimer timer("operation_name");
|
|
* // ... code to time ...
|
|
* } // Timer automatically ends here
|
|
*/
|
|
class ScopedTimer {
|
|
public:
|
|
explicit ScopedTimer(const std::string& operation_name);
|
|
~ScopedTimer();
|
|
|
|
// Disable copy and move
|
|
ScopedTimer(const ScopedTimer&) = delete;
|
|
ScopedTimer& operator=(const ScopedTimer&) = delete;
|
|
ScopedTimer(ScopedTimer&&) = delete;
|
|
ScopedTimer& operator=(ScopedTimer&&) = delete;
|
|
|
|
private:
|
|
std::string operation_name_;
|
|
};
|
|
|
|
} // namespace gfx
|
|
} // namespace yaze
|
|
|
|
#endif // YAZE_APP_GFX_PERFORMANCE_PROFILER_H
|