Add I/O stats

Using /proc/self/io 'read_bytes' and 'write_bytes' fields which count only
reads/writes that hit the storage (i.e no cached reads).
pull/58/head
jackun 4 years ago committed by FlightlessMango
parent 534ca9416d
commit f8398c3e7a

@ -0,0 +1,27 @@
#include "iostats.h"
#include "string_utils.h"
#include <fstream>
pthread_t ioThread;
void *getIoStats(void *args) {
iostats *io = reinterpret_cast<iostats *>(args);
if (io) {
io->prev.read_bytes = io->curr.read_bytes;
io->prev.write_bytes = io->curr.write_bytes;
std::string line;
std::ifstream f("/proc/self/io");
while (std::getline(f, line)) {
if (starts_with(line, "read_bytes:")) {
try_stoull(io->curr.read_bytes, line.substr(12));
}
else if (starts_with(line, "write_bytes:")) {
try_stoull(io->curr.write_bytes, line.substr(13));
}
}
io->diff.read = (io->curr.read_bytes - io->prev.read_bytes) / (1024.f * 1024.f);
io->diff.write = (io->curr.write_bytes - io->prev.write_bytes) / (1024.f * 1024.f);
}
pthread_detach(ioThread);
return NULL;
}

@ -0,0 +1,22 @@
#pragma once
#include <pthread.h>
#include <inttypes.h>
extern pthread_t ioThread;
struct iostats {
struct {
unsigned long long read_bytes;
unsigned long long write_bytes;
} curr;
struct {
unsigned long long read_bytes;
unsigned long long write_bytes;
} prev;
struct {
float read;
float write;
} diff;
};
void *getIoStats(void *args);

@ -41,6 +41,7 @@ vklayer_files = files(
'file_utils.cpp',
'memory.cpp',
'config.cpp',
'iostats.cpp',
)
# lib_xnvctrl = cc.find_library('XNVCtrl')

@ -54,6 +54,7 @@
#include "logging.h"
#include "keybinds.h"
#include "cpu.h"
#include "iostats.h"
#include "loaders/loader_nvml.h"
bool open = false;
@ -223,6 +224,8 @@ struct swapchain_data {
/* Over fps_sampling_period */
struct frame_stat accumulated_stats;
struct iostats io;
};
static const VkQueryPipelineStatisticFlags overlay_query_flags =
@ -986,6 +989,7 @@ static void snapshot_swapchain_frame(struct swapchain_data *data)
// get ram usage/max
pthread_create(&memoryThread, NULL, &update_meminfo, NULL);
pthread_create(&ioThread, NULL, &getIoStats, &data->io);
// update variables for logging
// cpuLoadLog = cpuArray[0].value;
@ -1212,6 +1216,26 @@ static void compute_swapchain_display(struct swapchain_data *data)
ImGui::Text("GB");
ImGui::PopFont();
}
if (instance_data->params.io_read){
auto sampling = instance_data->params.fps_sampling_period;
ImGui::TextColored(ImVec4(0.760, 0.576, 0.4, 1.00f), "IO rd");
ImGui::SameLine(hudFirstRow);
ImGui::Text("%.2f", data->io.diff.read * (1000000 / sampling));
ImGui::SameLine(0,1.0f);
ImGui::PushFont(data->font1);
ImGui::Text("MiB/s");
ImGui::PopFont();
}
if (instance_data->params.io_write){
auto sampling = instance_data->params.fps_sampling_period;
ImGui::TextColored(ImVec4(0.760, 0.576, 0.4, 1.00f), "IO wr");
ImGui::SameLine(hudFirstRow);
ImGui::Text("%.2f", data->io.diff.write * (1000000 / sampling));
ImGui::SameLine(0,1.0f);
ImGui::PushFont(data->font1);
ImGui::Text("MiB/s");
ImGui::PopFont();
}
if (instance_data->params.enabled[OVERLAY_PARAM_ENABLED_fps]){
ImGui::TableNextRow();
ImGui::TextColored(ImVec4(0.925, 0.411, 0.411, 1.00f), "%s", engineName.c_str());

@ -147,6 +147,8 @@ parse_str(const char *str)
#define parse_offset_x(s) parse_unsigned(s)
#define parse_offset_y(s) parse_unsigned(s)
#define parse_time_format(s) parse_str(s)
#define parse_io_read(s) parse_unsigned(s)
#define parse_io_write(s) parse_unsigned(s)
#define parse_crosshair_color(s) parse_color(s)

@ -73,6 +73,8 @@ extern "C" {
OVERLAY_PARAM_CUSTOM(crosshair_color) \
OVERLAY_PARAM_CUSTOM(background_alpha) \
OVERLAY_PARAM_CUSTOM(time_format) \
OVERLAY_PARAM_CUSTOM(io_read) \
OVERLAY_PARAM_CUSTOM(io_write) \
OVERLAY_PARAM_CUSTOM(help)
enum overlay_param_position {
@ -102,6 +104,7 @@ struct overlay_params {
bool help;
bool no_display;
bool full;
bool io_read, io_write;
unsigned width;
unsigned height;
unsigned offset_x;

@ -73,4 +73,15 @@ static bool try_stoi(int& val, const std::string& str, std::size_t* pos = 0, int
return false;
}
static bool try_stoull(unsigned long long& val, const std::string& str, std::size_t* pos = 0, int base = 10)
{
try {
val = std::stoull(str, pos, base);
return true;
} catch (std::invalid_argument& e) {
std::cerr << __func__ << ": invalid argument: '" << str << "'" << std::endl;
}
return false;
}
#pragma GCC diagnostic pop

Loading…
Cancel
Save