PerformanceCounters: Ignore reset boundary sample

Establish a fresh frame-time baseline after reset and average only valid
frame intervals.
pull/3800/head
Stenzek 6 days ago
parent b54fc14bcf
commit 8051b4f0c4
No known key found for this signature in database

@ -4,8 +4,8 @@
#include "performance_counters.h"
#include "gpu.h"
#include "gpu_backend.h"
#include "system.h"
#include "host.h"
#include "system.h"
#include "video_thread.h"
#include "util/media_capture.h"
@ -15,6 +15,7 @@
#include "common/threading.h"
#include "common/timer.h"
#include <limits>
#include <utility>
LOG_CHANNEL(PerfMon);
@ -23,10 +24,12 @@ namespace PerformanceCounters {
namespace {
static constexpr Timer::Value INVALID_FRAME_TIME = std::numeric_limits<Timer::Value>::max();
struct State
{
Timer::Value last_update_time;
Timer::Value last_frame_time;
Timer::Value last_frame_time = INVALID_FRAME_TIME;
u32 last_frame_number;
u32 last_internal_frame_number;
@ -35,6 +38,7 @@ struct State
float average_frame_time_accumulator;
float minimum_frame_time_accumulator;
float maximum_frame_time_accumulator;
u32 frame_time_samples;
float vps;
float fps;
@ -44,12 +48,12 @@ struct State
float maximum_frame_time;
float average_frame_time;
u64 last_core_thread_time;
float core_thread_usage;
u64 last_core_thread_time;
float core_thread_time;
u64 last_video_thread_time;
float video_thread_usage;
u64 last_video_thread_time;
float video_thread_time;
float average_gpu_time;
@ -147,35 +151,36 @@ void PerformanceCounters::Clear()
void PerformanceCounters::Reset()
{
DebugAssert(Host::IsOnCoreThread());
VideoThread::RunOnThread(
[frame_number = System::GetFrameNumber(), internal_frame_number = System::GetInternalFrameNumber()]() {
const Timer::Value now_ticks = Timer::GetCurrentValue();
s_state.last_frame_time = now_ticks;
s_state.last_update_time = now_ticks;
s_state.last_frame_number = frame_number;
s_state.last_internal_frame_number = internal_frame_number;
s_state.last_core_thread_time = Host::GetCoreThreadHandle().GetCPUTime();
s_state.last_video_thread_time = VideoThread::GetThreadHandle().GetCPUTime();
s_state.average_frame_time_accumulator = 0.0f;
s_state.minimum_frame_time_accumulator = 0.0f;
s_state.maximum_frame_time_accumulator = 0.0f;
});
VideoThread::RunOnThread([]() {
s_state.last_frame_time = INVALID_FRAME_TIME;
s_state.average_frame_time_accumulator = 0.0f;
s_state.minimum_frame_time_accumulator = 0.0f;
s_state.maximum_frame_time_accumulator = 0.0f;
s_state.frame_time_samples = 0;
});
}
void PerformanceCounters::Update(GPUBackend* gpu, u32 frame_number, u32 internal_frame_number)
{
const Timer::Value now_ticks = Timer::GetCurrentValue();
const float frame_time = static_cast<float>(
Timer::ConvertValueToMilliseconds(now_ticks - std::exchange(s_state.last_frame_time, now_ticks)));
s_state.minimum_frame_time_accumulator = (s_state.minimum_frame_time_accumulator == 0.0f) ?
frame_time :
std::min(s_state.minimum_frame_time_accumulator, frame_time);
const Timer::Value last_frame_time = std::exchange(s_state.last_frame_time, now_ticks);
if (last_frame_time == INVALID_FRAME_TIME)
{
s_state.last_update_time = now_ticks;
s_state.last_frame_number = frame_number;
s_state.last_internal_frame_number = internal_frame_number;
s_state.last_core_thread_time = Host::GetCoreThreadHandle().GetCPUTime();
s_state.last_video_thread_time = VideoThread::GetThreadHandle().GetCPUTime();
return;
}
const float frame_time = static_cast<float>(Timer::ConvertValueToMilliseconds(now_ticks - last_frame_time));
s_state.minimum_frame_time_accumulator =
(s_state.frame_time_samples == 0) ? frame_time : std::min(s_state.minimum_frame_time_accumulator, frame_time);
s_state.average_frame_time_accumulator += frame_time;
s_state.maximum_frame_time_accumulator = std::max(s_state.maximum_frame_time_accumulator, frame_time);
s_state.frame_time_samples++;
s_state.frame_time_history[s_state.frame_time_history_pos] = frame_time;
s_state.frame_time_history_pos = (s_state.frame_time_history_pos + 1) % NUM_FRAME_TIME_SAMPLES;
@ -199,9 +204,16 @@ void PerformanceCounters::Update(GPUBackend* gpu, u32 frame_number, u32 internal
const double time_divider = 1000.0 * (1.0 / static_cast<double>(Threading::GetThreadTicksPerSecond())) *
(1.0 / static_cast<double>(frames_runf));
s_state.minimum_frame_time = std::exchange(s_state.minimum_frame_time_accumulator, 0.0f);
s_state.average_frame_time = std::exchange(s_state.average_frame_time_accumulator, 0.0f) / frames_runf;
s_state.maximum_frame_time = std::exchange(s_state.maximum_frame_time_accumulator, 0.0f);
const float minimum_frame_time = std::exchange(s_state.minimum_frame_time_accumulator, 0.0f);
const float average_frame_time = std::exchange(s_state.average_frame_time_accumulator, 0.0f);
const float maximum_frame_time = std::exchange(s_state.maximum_frame_time_accumulator, 0.0f);
const u32 frame_time_samples = std::exchange(s_state.frame_time_samples, 0);
if (frame_time_samples > 0)
{
s_state.minimum_frame_time = minimum_frame_time;
s_state.average_frame_time = average_frame_time / static_cast<float>(frame_time_samples);
s_state.maximum_frame_time = maximum_frame_time;
}
s_state.vps = static_cast<float>(frames_runf / time);
s_state.fps = static_cast<float>(internal_frames_run) / time;

Loading…
Cancel
Save