WIP: gpu ms and cpu ms

This commit checks the cpu time and gpu time spent in the process to determine
how much cpu and gpu time is spent per frame
gpu_cpu_ms
FlightlessMango 9 months ago
parent 3922da8a39
commit ae39f680bd

@ -190,5 +190,17 @@ void getAmdGpuInfo(){
value = 0;
gpu_info.voltage = value;
}
if (amdgpu.fdinfo){
rewind(amdgpu.fdinfo);
fflush(amdgpu.fdinfo);
char line[256];
while (fgets(line, sizeof(line), amdgpu.fdinfo))
if(strstr(line, "drm-engine-gfx"))
sscanf(line, "drm-engine-gfx: %" SCNu64 " ns", &value);
gpu_info.app_busy_ns = value;
}
#endif
}

@ -21,6 +21,7 @@ struct amdgpu_files
FILE *gtt_used;
FILE *fan;
FILE *gpu_voltage_soc;
FILE *fdinfo;
};
extern amdgpu_files amdgpu;
@ -44,6 +45,7 @@ struct gpuInfo{
float gtt_used;
int fan_speed;
int voltage;
uint64_t app_busy_ns;
};
extern struct gpuInfo gpu_info;

@ -3,6 +3,7 @@
#include <functional>
#include <sstream>
#include <cmath>
#include <numeric>
#include "overlay.h"
#include "overlay_params.h"
#include "hud_elements.h"
@ -271,6 +272,17 @@ void HudElements::gpu_stats(){
HUDElements.TextColored(HUDElements.colors.text, "mV");
ImGui::PopFont();
}
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_gpu_ms]){
ImguiNextColumnOrNewRow();
double sum = std::accumulate(HUDElements.gputimes_data.begin(), HUDElements.gputimes_data.end(), 0.000);
double gputimes_avg = sum / HUDElements.gputimes_data.size();
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.1f", gputimes_avg);
ImGui::SameLine(0, 1.0f);
ImGui::PushFont(HUDElements.sw_stats->font1);
HUDElements.TextColored(HUDElements.colors.text, "ms");
ImGui::PopFont();
}
}
}
@ -345,6 +357,17 @@ void HudElements::cpu_stats(){
HUDElements.TextColored(HUDElements.colors.text, "W");
ImGui::PopFont();
}
if (HUDElements.params->enabled[OVERLAY_PARAM_ENABLED_cpu_ms]){
ImguiNextColumnOrNewRow();
double sum = std::accumulate(HUDElements.cputimes_data.begin(), HUDElements.cputimes_data.end(), 0.000);
double cputimes_avg = sum / HUDElements.cputimes_data.size();
right_aligned_text(HUDElements.colors.text, HUDElements.ralign_width, "%.1f", cputimes_avg);
ImGui::SameLine(0, 1.0f);
ImGui::PushFont(HUDElements.sw_stats->font1);
HUDElements.TextColored(HUDElements.colors.text, "ms");
ImGui::PopFont();
}
}
}

@ -29,6 +29,8 @@ class HudElements{
std::vector<std::pair<void(*)(), std::string >> ordered_functions;
std::vector<float> gamescope_debug_latency {};
std::vector<float> gamescope_debug_app {};
std::vector<float> cputimes_data;
std::vector<float> gputimes_data;
int min, max, gpu_core_max, gpu_mem_max, cpu_temp_max, gpu_temp_max;
const std::vector<std::string> permitted_params = {
"gpu_load", "cpu_load", "gpu_core_clock", "gpu_mem_clock",

@ -892,6 +892,15 @@ void init_gpu_stats(uint32_t& vendorID, uint32_t reported_deviceID, overlay_para
}
}
for (const auto& file : fs::directory_iterator("/proc/self/fdinfo")){
std::ifstream f(file.path().string());
std::string line;
if (f)
while (std::getline(f, line))
if (line.find("amdgpu") != std::string::npos)
amdgpu.fdinfo = fopen(file.path().string().c_str(), "r");
}
if (!metrics_path.empty())
break;

@ -104,6 +104,8 @@ typedef unsigned long KeySym;
OVERLAY_PARAM_BOOL(temp_fahrenheit) \
OVERLAY_PARAM_BOOL(dynamic_frame_timing) \
OVERLAY_PARAM_BOOL(duration) \
OVERLAY_PARAM_BOOL(cpu_ms) \
OVERLAY_PARAM_BOOL(gpu_ms) \
OVERLAY_PARAM_CUSTOM(fps_sampling_period) \
OVERLAY_PARAM_CUSTOM(output_folder) \
OVERLAY_PARAM_CUSTOM(output_file) \

@ -38,6 +38,8 @@
#include <inttypes.h>
#include <spdlog/spdlog.h>
#include <imgui.h>
#include <unistd.h>
#include <numeric>
#include "mesa/util/macros.h" // defines "restrict" for vk_util.h
#include "mesa/util/os_socket.h"
@ -50,6 +52,7 @@
#include "notify.h"
#include "blacklist.h"
#include "pci_ids.h"
#include "gpu.h"
using namespace std;
@ -1571,10 +1574,50 @@ static void overlay_DestroySwapchainKHR(
destroy_swapchain_data(swapchain_data);
}
static unsigned long long getProcessCpuTimeTicks() {
std::ifstream stat_file("/proc/self/stat");
std::string stat_data;
if (!stat_file) {
std::cerr << "Failed to open /proc/self/stat" << std::endl;
return 0;
}
getline(stat_file, stat_data);
stat_file.close();
unsigned long long utime, stime;
std::istringstream iss(stat_data);
for (int i = 1; i <= 13; ++i) {
iss.ignore(std::numeric_limits<std::streamsize>::max(), ' ');
}
iss >> utime >> stime; // The 14th and 15th fields in /proc/self/stat
return utime + stime;
}
static uint64_t getGpuTime() {
rewind(amdgpu.fdinfo);
fflush(amdgpu.fdinfo);
char line[256];
uint64_t val;
while (fgets(line, sizeof(line), amdgpu.fdinfo))
if(strstr(line, "drm-engine-gfx"))
sscanf(line, "drm-engine-gfx: %" SCNu64 " ns", &val);
return val;
}
static VkResult overlay_QueuePresentKHR(
VkQueue queue,
const VkPresentInfoKHR* pPresentInfo)
{
unsigned long long startCpuTime = getProcessCpuTimeTicks();
static bool gpu_keep_last = false;
static uint64_t startGpuTime;
if (!gpu_keep_last)
startGpuTime = getGpuTime();
using namespace std::chrono_literals;
if (fps_limit_stats.targetFrameTime > 0s && fps_limit_stats.method == FPS_LIMIT_METHOD_EARLY){
fps_limit_stats.frameStart = Clock::now();
@ -1629,6 +1672,26 @@ static VkResult overlay_QueuePresentKHR(
FpsLimiter(fps_limit_stats);
fps_limit_stats.frameEnd = Clock::now();
}
// Calculate the GPU time used for this frame in milliseconds
uint64_t endGpuTime = getGpuTime();
if (endGpuTime > startGpuTime){
double gpuTime = static_cast<double>(endGpuTime - startGpuTime) / 1000000.0;
HUDElements.gputimes_data.push_back(gpuTime);
if (HUDElements.gputimes_data.size() > 199)
HUDElements.gputimes_data.erase(HUDElements.gputimes_data.begin());
gpu_keep_last = false;
} else {
gpu_keep_last = true;
}
// Calculate the CPU time used for this frame in milliseconds
unsigned long long endCpuTime = getProcessCpuTimeTicks();
unsigned long long cpuTimeTicks = endCpuTime - startCpuTime;
double cpuTime = static_cast<double>(cpuTimeTicks) * 1000.0 / sysconf(_SC_CLK_TCK);
HUDElements.cputimes_data.push_back(cpuTime);
if (HUDElements.cputimes_data.size() > 199)
HUDElements.cputimes_data.erase(HUDElements.cputimes_data.begin());
return result;
}

Loading…
Cancel
Save