implement configurable benchmark percentiles.

pull/236/head
Kingsley McDonald 4 years ago
parent 0d03b5a150
commit aa77a351de

@ -117,5 +117,11 @@ background_alpha=0.5
# log_duration
### Define name and location of the output file (Required for logging)
# output_file
<<<<<<< HEAD
### Permit uploading logs directly to Flightlessmango.com
# permit_upload=1
# permit_upload=1
=======
### Define a '+'-separated list of percentiles shown in the benchmark results.
### Use "AVG" to get a mean average. Default percentiles are 97+AVG+1+0.1
# benchmark_percentiles=
>>>>>>> 6d4ed4e... implement configurable benchmark percentiles.

@ -750,7 +750,7 @@ void check_keybinds(struct swapchain_stats& sw_stats, struct overlay_params& par
last_f2_press = now;
if(loggingOn){
log_end = now;
std::thread(calculate_benchmark_data).detach();
std::thread(calculate_benchmark_data, &params).detach();
} else {
logUpdate = false;
std::thread(update_hw_info, std::ref(sw_stats), std::ref(params), vendorID).detach();
@ -805,27 +805,38 @@ void check_keybinds(struct swapchain_stats& sw_stats, struct overlay_params& par
}
}
void calculate_benchmark_data(){
vector<float> sorted;
sorted = benchmark.fps_data;
void calculate_benchmark_data(void *params_void){
overlay_params *params = reinterpret_cast<overlay_params *>(params_void);
vector<float> sorted = benchmark.fps_data;
sort(sorted.begin(), sorted.end());
// 97th percentile
int index = sorted.size() * 0.97;
benchmark.ninety = sorted[index];
// avg
benchmark.percentile_data.clear();
benchmark.total = 0.f;
for (auto fps_ : sorted){
benchmark.total = benchmark.total + fps_;
}
benchmark.avg = benchmark.total / sorted.size();
// 1% min
benchmark.total = 0.f;
for (size_t i = 0; i < sorted.size() * 0.01; i++){
benchmark.total = sorted[i];
for (std::string percentile : params->benchmark_percentiles) {
float result;
// special case handling for a mean-based average
if (percentile.find("AVG") == 0) {
result = benchmark.total / sorted.size();
}
// everything else is used to calculate percentiles
else {
char *endChar;
float fraction = std::strtof(percentile.c_str(), &endChar) / 100;
if (*endChar != '%' || fraction <= 0.0 || fraction > 1.0) {
std::cerr << "MANGOHUD: Invalid percentile value for benchmark: '" << percentile << "'\n";
continue;
}
result = sorted[(fraction * sorted.size()) - 1];
}
benchmark.percentile_data.push_back({percentile, result});
}
benchmark.oneP = benchmark.total;
// 0.1% min
benchmark.pointOneP = sorted[sorted.size() * 0.001];
}
void update_hud_info(struct swapchain_stats& sw_stats, struct overlay_params& params, uint32_t vendorID){
@ -1040,14 +1051,13 @@ static void render_mpris_metadata(struct overlay_params& params, metadata& meta,
void render_benchmark(swapchain_stats& data, struct overlay_params& params, ImVec2& window_size, unsigned height, uint64_t now){
// TODO, FIX LOG_DURATION FOR BENCHMARK
int benchHeight = 6 * params.font_size + 10.0f + 58;
int benchHeight = (2 + benchmark.percentile_data.size()) * params.font_size + 10.0f + 58;
ImGui::SetNextWindowSize(ImVec2(window_size.x, benchHeight), ImGuiCond_Always);
if (height - (window_size.y + data.main_window_pos.y + 5) < benchHeight)
ImGui::SetNextWindowPos(ImVec2(data.main_window_pos.x, data.main_window_pos.y - benchHeight - 5), ImGuiCond_Always);
else
ImGui::SetNextWindowPos(ImVec2(data.main_window_pos.x, data.main_window_pos.y + window_size.y + 5), ImGuiCond_Always);
vector<pair<string, float>> benchmark_data = {{"97% ", benchmark.ninety}, {"AVG ", benchmark.avg}, {"1% ", benchmark.oneP}, {"0.1%", benchmark.pointOneP}};
float display_time = float(now - log_end) / 1000000;
static float display_for = 10.0f;
float alpha;
@ -1085,7 +1095,7 @@ void render_benchmark(swapchain_stats& data, struct overlay_params& params, ImVe
snprintf(duration, sizeof(duration), "Duration: %.1fs", float(log_end - log_start) / 1000000);
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2 )- (ImGui::CalcTextSize(duration).x / 2));
ImGui::TextColored(ImVec4(1.0, 1.0, 1.0, alpha / params.background_alpha), "%s", duration);
for (auto& data_ : benchmark_data){
for (auto& data_ : benchmark.percentile_data){
char buffer[20];
snprintf(buffer, sizeof(buffer), "%s %.1f", data_.first.c_str(), data_.second);
ImGui::SetCursorPosX((ImGui::GetWindowSize().x / 2 )- (ImGui::CalcTextSize(buffer).x / 2));
@ -1394,7 +1404,7 @@ void render_imgui(swapchain_stats& data, struct overlay_params& params, ImVec2&
if (loggingOn && params.log_duration && (now - log_start) >= params.log_duration * 1000000){
loggingOn = false;
log_end = now;
std::thread(calculate_benchmark_data).detach();
std::thread(calculate_benchmark_data, &params).detach();
}
if((now - log_end) / 1000000 < 12)
render_benchmark(data, params, window_size, height, now);

@ -52,12 +52,9 @@ struct fps_limit {
};
struct benchmark_stats {
float ninety;
float avg;
float oneP;
float pointOneP;
float total;
std::vector<float> fps_data;
std::vector<std::pair<std::string, float>> percentile_data;
};
extern struct fps_limit fps_limit_stats;
@ -75,5 +72,5 @@ void init_system_info(void);
void FpsLimiter(struct fps_limit& stats);
void imgui_custom_style(struct overlay_params& params);
void get_device_name(int32_t vendorID, int32_t deviceID, struct swapchain_stats& sw_stats);
void calculate_benchmark_data(void);
void calculate_benchmark_data(void *params_void);
void create_fonts(const overlay_params& params, ImFont*& default_font, ImFont*& small_font);

@ -202,6 +202,36 @@ parse_media_player_order(const char *str)
return order;
}
static std::vector<std::string>
parse_benchmark_percentiles(const char *str)
{
std::vector<std::string> percentiles;
std::stringstream percentStrings(str);
std::string value;
size_t maxLength = 0; // for padding later on
while (std::getline(percentStrings, value, '+')) {
trim(value);
// everything except AVG is assumed to be a percentile.
if (value != "AVG")
value += '%';
percentiles.push_back(value);
if (value.length() > maxLength)
maxLength = value.length();
}
// now reiterate over the strings and add equal padding
for (size_t i = 0; i < percentiles.size(); i++) {
percentiles[i].append(maxLength - percentiles[i].length(), ' ');
}
return percentiles;
}
#define parse_width(s) parse_unsigned(s)
#define parse_height(s) parse_unsigned(s)
#define parse_vsync(s) parse_unsigned(s)
@ -392,7 +422,11 @@ parse_overlay_config(struct overlay_params *params,
params->font_scale_media_player = 0.55f;
params->log_interval = 100;
params->media_player_order = { MP_ORDER_TITLE, MP_ORDER_ARTIST, MP_ORDER_ALBUM };
<<<<<<< HEAD
params->permit_upload = 0;
=======
params->benchmark_percentiles = { "97% ", "AVG ", "1% ", "0.1%" };
>>>>>>> 6d4ed4e... implement configurable benchmark percentiles.
#ifdef HAVE_X11
params->toggle_hud = { XK_Shift_R, XK_F12 };

@ -89,7 +89,11 @@ typedef unsigned long KeySym;
OVERLAY_PARAM_CUSTOM(cpu_text) \
OVERLAY_PARAM_CUSTOM(gpu_text) \
OVERLAY_PARAM_CUSTOM(log_interval) \
<<<<<<< HEAD
OVERLAY_PARAM_CUSTOM(permit_upload) \
=======
OVERLAY_PARAM_CUSTOM(benchmark_percentiles) \
>>>>>>> 6d4ed4e... implement configurable benchmark percentiles.
OVERLAY_PARAM_CUSTOM(help)
enum overlay_param_position {
@ -152,6 +156,7 @@ struct overlay_params {
std::string cpu_text, gpu_text;
unsigned log_interval;
std::vector<media_player_order> media_player_order;
std::vector<std::string> benchmark_percentiles;
std::string config_file_path;
std::unordered_map<std::string,std::string> options;

Loading…
Cancel
Save