Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] hud: Modify histogram to use buckets and report p50/p90/p99 #659

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 35 additions & 3 deletions src/hud_elements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -537,9 +537,41 @@ void HudElements::frame_timing(){
double min_time = 0.0f;
double max_time = 50.0f;
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_histogram]){
ImGui::PlotHistogram(hash, get_time_stat, HUDElements.sw_stats,
ARRAY_SIZE(HUDElements.sw_stats->frames_stats), 0,
NULL, min_time, max_time,
float *ft = HUDElements.sw_stats->frame_times;
size_t ft_size = ARRAY_SIZE(HUDElements.sw_stats->frame_times);
uint32_t tsmin=0, tsmax=0;
uint32_t p50=0, p90=0, p99=0;
// one frame latency between this and update_hud_info_with_frametime.
// That makes p99 only kick in after 100 frames.
uint32_t frame_count = std::min((size_t)HUDElements.sw_stats->n_frames, ARRAY_SIZE(HUDElements.sw_stats->frames_stats));
uint32_t frames_seen = 0;
uint32_t height = 0;
for(uint32_t i = 0; i < ft_size; i++) {
frames_seen += ft[i];
if(ft[i] > height) { height = ft[i]; }
if(tsmin == 0 && ft[i] > 0) { tsmin = i; }
if(i > tsmax && ft[i] > 0) { tsmax = i; }
if(p50 == 0 && frames_seen >= frame_count/2) {
p50 = i;
}
if(p90 == 0 && frames_seen >= frame_count - (frame_count/10)) {
p90 = i;
}
if(p99 == 0 && frames_seen >= frame_count - (frame_count/100)) {
p99 = i;
}
}
ImGui::PushFont(HUDElements.sw_stats->font1);
ImGui::TextColored(HUDElements.colors.text, "p50/p90/p99");
ImGui::TextColored(HUDElements.colors.text, "%3d/%3d/%3d ms", p50, p90, p99);
// ImGui::TextColored(HUDElements.colors.text, "s:%d,c:%d,h:%d", frames_seen, frame_count, height);
ImGui::TextColored(HUDElements.colors.text, "min:%d,max:%d", tsmin, tsmax);
ImGui::PopFont();
ImGui::TableNextRow(); ImGui::TableNextColumn();
// Draw at least 16 buckets.
ImGui::PlotHistogram(hash, ft,
std::max(tsmax, 16u), tsmin,
NULL, 0, height,
ImVec2(ImGui::GetContentRegionAvailWidth() * HUDElements.params->table_columns, 50));
} else {
ImGui::PlotLines(hash, get_time_stat, HUDElements.sw_stats,
Expand Down
12 changes: 12 additions & 0 deletions src/overlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,18 @@ void update_hud_info_with_frametime(struct swapchain_stats& sw_stats, struct ove
if (sw_stats.last_present_time) {
sw_stats.frames_stats[f_idx].stats[OVERLAY_PLOTS_frame_timing] =
frametime_ns;
uint32_t frametime_ms = frametime_ns/1000000;
if (frametime_ms < 1000) {
sw_stats.frame_times[frametime_ms] += 1.0;
}
// keep the histogram for the same window as the normal frame graph.
if (sw_stats.n_frames >= ARRAY_SIZE(sw_stats.frames_stats)) {
uint32_t fp_idx = (sw_stats.n_frames + 1) % ARRAY_SIZE(sw_stats.frames_stats);
uint32_t oldest_frametime_ms = sw_stats.frames_stats[fp_idx].stats[OVERLAY_PLOTS_frame_timing]/1000000;
if(oldest_frametime_ms < 1000) {
sw_stats.frame_times[oldest_frametime_ms] -= 1.0;
}
}
}

frametime = frametime_ns / 1000;
Expand Down
3 changes: 2 additions & 1 deletion src/overlay.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ struct swapchain_stats {
double time_dividor;
struct frame_stat stats_min, stats_max;
struct frame_stat frames_stats[200];
float frame_times[1000]; // histogram buckets.

ImFont* font1 = nullptr;
ImFont* font_text = nullptr;
Expand Down Expand Up @@ -167,4 +168,4 @@ extern void process_control_socket(struct instance_data *instance_data);
void render_mpris_metadata(overlay_params& params, mutexed_metadata& meta, uint64_t frame_timing);
#endif

#endif //MANGOHUD_OVERLAY_H
#endif //MANGOHUD_OVERLAY_H