overlay: avoid quadratic behavior

Using a vector with erase(begin()) results in a copy of the full array
every time. This is inefficient and in the case of HUD graphs, was having
quadratic complexity which can noticeably affect performance.

This patch replaces most of the operations with an O(1) alternative,
keeping the total cost under a linear bound. While on this, also refactor
the size of graph array into a constant.
pull/657/head
Tatsuyuki Ishi 2 years ago
parent ee7f3fbfd2
commit ada173e67f

@ -698,13 +698,13 @@ void HudElements::graphs(){
ImGui::TableNextRow(); ImGui::TableNextColumn();
ImGui::Dummy(ImVec2(0.0f, real_font_size.y));
const std::string& value = HUDElements.ordered_functions[HUDElements.place].second;
std::vector<float> arr(50, 0);
assert(kMaxGraphEntries >= graph_data.size());
std::vector<float> arr(kMaxGraphEntries - graph_data.size());
ImGui::PushFont(HUDElements.sw_stats->font1);
if (value == "cpu_load"){
for (auto& it : graph_data){
arr.push_back(float(it.cpu_load));
arr.erase(arr.begin());
}
HUDElements.max = 100; HUDElements.min = 0;
ImGui::TextColored(HUDElements.colors.engine, "%s", "CPU Load");
@ -713,7 +713,6 @@ void HudElements::graphs(){
if (value == "gpu_load"){
for (auto& it : graph_data){
arr.push_back(float(it.gpu_load));
arr.erase(arr.begin());
}
HUDElements.max = 100; HUDElements.min = 0;
ImGui::TextColored(HUDElements.colors.engine, "%s", "GPU Load");
@ -722,7 +721,6 @@ void HudElements::graphs(){
if (value == "cpu_temp"){
for (auto& it : graph_data){
arr.push_back(float(it.cpu_temp));
arr.erase(arr.begin());
}
if (int(arr.back()) > HUDElements.cpu_temp_max)
HUDElements.cpu_temp_max = arr.back();
@ -735,7 +733,6 @@ void HudElements::graphs(){
if (value == "gpu_temp"){
for (auto& it : graph_data){
arr.push_back(float(it.gpu_temp));
arr.erase(arr.begin());
}
if (int(arr.back()) > HUDElements.gpu_temp_max)
HUDElements.gpu_temp_max = arr.back();
@ -748,7 +745,6 @@ void HudElements::graphs(){
if (value == "gpu_core_clock"){
for (auto& it : graph_data){
arr.push_back(float(it.gpu_core_clock));
arr.erase(arr.begin());
}
if (int(arr.back()) > HUDElements.gpu_core_max)
HUDElements.gpu_core_max = arr.back();
@ -761,7 +757,6 @@ void HudElements::graphs(){
if (value == "gpu_mem_clock"){
for (auto& it : graph_data){
arr.push_back(float(it.gpu_mem_clock));
arr.erase(arr.begin());
}
if (int(arr.back()) > HUDElements.gpu_mem_max)
HUDElements.gpu_mem_max = arr.back();
@ -774,7 +769,6 @@ void HudElements::graphs(){
if (value == "vram"){
for (auto& it : graph_data){
arr.push_back(float(it.gpu_vram_used));
arr.erase(arr.begin());
}
HUDElements.max = gpu_info.memoryTotal;
@ -787,7 +781,6 @@ void HudElements::graphs(){
HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_ram] = true;
for (auto& it : graph_data){
arr.push_back(float(it.ram_used));
arr.erase(arr.begin());
}
HUDElements.max = memmax;

@ -40,7 +40,7 @@ bool gui_open = false;
struct benchmark_stats benchmark;
struct fps_limit fps_limit_stats {};
ImVec2 real_font_size;
std::vector<logData> graph_data;
std::deque<logData> graph_data;
const char* engines[] = {"Unknown", "OpenGL", "VULKAN", "DXVK", "VKD3D", "DAMAVAND", "ZINK", "WINED3D", "Feral3D", "ToGL", "GAMESCOPE"};
overlay_params *_params {};
@ -90,8 +90,8 @@ void update_hw_info(struct swapchain_stats& sw_stats, struct overlay_params& par
currentLogData.cpu_load = cpuStats.GetCPUDataTotal().percent;
currentLogData.cpu_temp = cpuStats.GetCPUDataTotal().temp;
// Save data for graphs
if (graph_data.size() > 50)
graph_data.erase(graph_data.begin());
if (graph_data.size() >= kMaxGraphEntries)
graph_data.pop_front();
graph_data.push_back(currentLogData);
logger->notify_data_valid();
HUDElements.update_exec();

@ -5,6 +5,7 @@
#include <string>
#include <stdint.h>
#include <vector>
#include <deque>
#include <imgui.h>
#include "overlay_params.h"
#include "iostats.h"
@ -24,6 +25,8 @@ struct frame_stat {
uint64_t stats[OVERLAY_PLOTS_MAX];
};
static const int kMaxGraphEntries = 50;
enum EngineTypes
{
UNKNOWN,
@ -139,7 +142,7 @@ extern int32_t deviceID;
extern struct benchmark_stats benchmark;
extern ImVec2 real_font_size;
extern std::string wineVersion;
extern std::vector<logData> graph_data;
extern std::deque<logData> graph_data;
extern overlay_params *_params;
void position_layer(struct swapchain_stats& data, struct overlay_params& params, ImVec2 window_size);

Loading…
Cancel
Save