make cpu wayyy cleaner

This commit is contained in:
drath
2025-09-14 11:03:55 +02:00
parent 89a94b1822
commit 2ebc62d063
3 changed files with 862 additions and 187 deletions

View File

@@ -1,14 +1,19 @@
#ifndef GPU_HPP
#define GPU_HPP
/* see which we actually need now */
#include <cstdint>
#include <fstream>
#include <print>
#include <string>
#include <utils.hpp>
#define REL_METRICS_PATH = "/../../gpu_metrics"
#include <gpu_structs.hpp>
#define REL_METRICS_PATH "/../../gpu_metrics"
#define MAX_METRICS_LENGTH 512
/* should refactor this struct so its a little cleaner and closer to gpu_metrics */
struct gpu_t {
uint16_t fan_speed = 0;
uint16_t core_clock = 0;
@@ -31,15 +36,8 @@ struct gpu_t {
uint8_t umc_usage = 0;
};
struct GpuMetricsHeader_t {
uint16_t structure_size = 0;
uint8_t format_revision = 0;
uint8_t content_revision = 0;
};
std::string detectGpuHwmon(std::string pci);
gpu_t getGpu(GpuMetricsHeader_t header, std::string hw);
bool checkForMetrics(std::string hwmon);
gpu_t getGpu(std::string hw, bool hasMetrics);
GpuMetricsHeader_t getGpuMetricsHeader(std::string path);
#endif
#endif

795
include/gpu_structs.hpp Normal file
View File

@@ -0,0 +1,795 @@
#include <cstdint>
/* STRUCTS COPIED WHOLESALE FROM LINUX SOURCE CODE, formatted and wrapped around a namespace
https://github.com/torvalds/linux/blob/master/drivers/gpu/drm/amd/include/kgd_pp_interface.h */
#define NUM_HBM_INSTANCES 4
#define NUM_XGMI_LINKS 8
#define MAX_GFX_CLKS 8
#define MAX_CLKS 4
#define NUM_VCN 4
#define NUM_JPEG_ENG 32
#define NUM_JPEG_ENG_V1 40
#define MAX_XCC 8
#define NUM_XCP 8
namespace gpu {
struct metrics_table_header {
uint16_t structure_size;
uint8_t format_revision;
uint8_t content_revision;
};
/*
* gpu_metrics_v1_0 is not recommended as it's not naturally aligned.
* Use gpu_metrics_v1_1 or later instead.
*/
struct gpu_metrics_v1_0 {
struct metrics_table_header common_header;
/* Driver attached timestamp (in ns) */
uint64_t system_clock_counter;
/* Temperature */
uint16_t temperature_edge;
uint16_t temperature_hotspot;
uint16_t temperature_mem;
uint16_t temperature_vrgfx;
uint16_t temperature_vrsoc;
uint16_t temperature_vrmem;
/* Utilization */
uint16_t average_gfx_activity;
uint16_t average_umc_activity; // memory controller
uint16_t average_mm_activity; // UVD or VCN
/* Power/Energy */
uint16_t average_socket_power;
uint32_t energy_accumulator;
/* Average clocks */
uint16_t average_gfxclk_frequency;
uint16_t average_socclk_frequency;
uint16_t average_uclk_frequency;
uint16_t average_vclk0_frequency;
uint16_t average_dclk0_frequency;
uint16_t average_vclk1_frequency;
uint16_t average_dclk1_frequency;
/* Current clocks */
uint16_t current_gfxclk;
uint16_t current_socclk;
uint16_t current_uclk;
uint16_t current_vclk0;
uint16_t current_dclk0;
uint16_t current_vclk1;
uint16_t current_dclk1;
/* Throttle status */
uint32_t throttle_status;
/* Fans */
uint16_t current_fan_speed;
/* Link width/speed */
uint8_t pcie_link_width;
uint8_t pcie_link_speed; // in 0.1 GT/s
};
struct gpu_metrics_v1_1 {
struct metrics_table_header common_header;
/* Temperature */
uint16_t temperature_edge;
uint16_t temperature_hotspot;
uint16_t temperature_mem;
uint16_t temperature_vrgfx;
uint16_t temperature_vrsoc;
uint16_t temperature_vrmem;
/* Utilization */
uint16_t average_gfx_activity;
uint16_t average_umc_activity; // memory controller
uint16_t average_mm_activity; // UVD or VCN
/* Power/Energy */
uint16_t average_socket_power;
uint64_t energy_accumulator;
/* Driver attached timestamp (in ns) */
uint64_t system_clock_counter;
/* Average clocks */
uint16_t average_gfxclk_frequency;
uint16_t average_socclk_frequency;
uint16_t average_uclk_frequency;
uint16_t average_vclk0_frequency;
uint16_t average_dclk0_frequency;
uint16_t average_vclk1_frequency;
uint16_t average_dclk1_frequency;
/* Current clocks */
uint16_t current_gfxclk;
uint16_t current_socclk;
uint16_t current_uclk;
uint16_t current_vclk0;
uint16_t current_dclk0;
uint16_t current_vclk1;
uint16_t current_dclk1;
/* Throttle status */
uint32_t throttle_status;
/* Fans */
uint16_t current_fan_speed;
/* Link width/speed */
uint16_t pcie_link_width;
uint16_t pcie_link_speed; // in 0.1 GT/s
uint16_t padding;
uint32_t gfx_activity_acc;
uint32_t mem_activity_acc;
uint16_t temperature_hbm[NUM_HBM_INSTANCES];
};
struct gpu_metrics_v1_2 {
struct metrics_table_header common_header;
/* Temperature */
uint16_t temperature_edge;
uint16_t temperature_hotspot;
uint16_t temperature_mem;
uint16_t temperature_vrgfx;
uint16_t temperature_vrsoc;
uint16_t temperature_vrmem;
/* Utilization */
uint16_t average_gfx_activity;
uint16_t average_umc_activity; // memory controller
uint16_t average_mm_activity; // UVD or VCN
/* Power/Energy */
uint16_t average_socket_power;
uint64_t energy_accumulator;
/* Driver attached timestamp (in ns) */
uint64_t system_clock_counter;
/* Average clocks */
uint16_t average_gfxclk_frequency;
uint16_t average_socclk_frequency;
uint16_t average_uclk_frequency;
uint16_t average_vclk0_frequency;
uint16_t average_dclk0_frequency;
uint16_t average_vclk1_frequency;
uint16_t average_dclk1_frequency;
/* Current clocks */
uint16_t current_gfxclk;
uint16_t current_socclk;
uint16_t current_uclk;
uint16_t current_vclk0;
uint16_t current_dclk0;
uint16_t current_vclk1;
uint16_t current_dclk1;
/* Throttle status (ASIC dependent) */
uint32_t throttle_status;
/* Fans */
uint16_t current_fan_speed;
/* Link width/speed */
uint16_t pcie_link_width;
uint16_t pcie_link_speed; // in 0.1 GT/s
uint16_t padding;
uint32_t gfx_activity_acc;
uint32_t mem_activity_acc;
uint16_t temperature_hbm[NUM_HBM_INSTANCES];
/* PMFW attached timestamp (10ns resolution) */
uint64_t firmware_timestamp;
};
struct gpu_metrics_v1_3 {
struct metrics_table_header common_header;
/* Temperature */
uint16_t temperature_edge;
uint16_t temperature_hotspot;
uint16_t temperature_mem;
uint16_t temperature_vrgfx;
uint16_t temperature_vrsoc;
uint16_t temperature_vrmem;
/* Utilization */
uint16_t average_gfx_activity;
uint16_t average_umc_activity; // memory controller
uint16_t average_mm_activity; // UVD or VCN
/* Power/Energy */
uint16_t average_socket_power;
uint64_t energy_accumulator;
/* Driver attached timestamp (in ns) */
uint64_t system_clock_counter;
/* Average clocks */
uint16_t average_gfxclk_frequency;
uint16_t average_socclk_frequency;
uint16_t average_uclk_frequency;
uint16_t average_vclk0_frequency;
uint16_t average_dclk0_frequency;
uint16_t average_vclk1_frequency;
uint16_t average_dclk1_frequency;
/* Current clocks */
uint16_t current_gfxclk;
uint16_t current_socclk;
uint16_t current_uclk;
uint16_t current_vclk0;
uint16_t current_dclk0;
uint16_t current_vclk1;
uint16_t current_dclk1;
/* Throttle status */
uint32_t throttle_status;
/* Fans */
uint16_t current_fan_speed;
/* Link width/speed */
uint16_t pcie_link_width;
uint16_t pcie_link_speed; // in 0.1 GT/s
uint16_t padding;
uint32_t gfx_activity_acc;
uint32_t mem_activity_acc;
uint16_t temperature_hbm[NUM_HBM_INSTANCES];
/* PMFW attached timestamp (10ns resolution) */
uint64_t firmware_timestamp;
/* Voltage (mV) */
uint16_t voltage_soc;
uint16_t voltage_gfx;
uint16_t voltage_mem;
uint16_t padding1;
/* Throttle status (ASIC independent) */
uint64_t indep_throttle_status;
};
struct gpu_metrics_v1_4 {
struct metrics_table_header common_header;
/* Temperature (Celsius) */
uint16_t temperature_hotspot;
uint16_t temperature_mem;
uint16_t temperature_vrsoc;
/* Power (Watts) */
uint16_t curr_socket_power;
/* Utilization (%) */
uint16_t average_gfx_activity;
uint16_t average_umc_activity; // memory controller
uint16_t vcn_activity[NUM_VCN];
/* Energy (15.259uJ (2^-16) units) */
uint64_t energy_accumulator;
/* Driver attached timestamp (in ns) */
uint64_t system_clock_counter;
/* Throttle status */
uint32_t throttle_status;
/* Clock Lock Status. Each bit corresponds to clock instance */
uint32_t gfxclk_lock_status;
/* Link width (number of lanes) and speed (in 0.1 GT/s) */
uint16_t pcie_link_width;
uint16_t pcie_link_speed;
/* XGMI bus width and bitrate (in Gbps) */
uint16_t xgmi_link_width;
uint16_t xgmi_link_speed;
/* Utilization Accumulated (%) */
uint32_t gfx_activity_acc;
uint32_t mem_activity_acc;
/*PCIE accumulated bandwidth (GB/sec) */
uint64_t pcie_bandwidth_acc;
/*PCIE instantaneous bandwidth (GB/sec) */
uint64_t pcie_bandwidth_inst;
/* PCIE L0 to recovery state transition accumulated count */
uint64_t pcie_l0_to_recov_count_acc;
/* PCIE replay accumulated count */
uint64_t pcie_replay_count_acc;
/* PCIE replay rollover accumulated count */
uint64_t pcie_replay_rover_count_acc;
/* XGMI accumulated data transfer size(KiloBytes) */
uint64_t xgmi_read_data_acc[NUM_XGMI_LINKS];
uint64_t xgmi_write_data_acc[NUM_XGMI_LINKS];
/* PMFW attached timestamp (10ns resolution) */
uint64_t firmware_timestamp;
/* Current clocks (Mhz) */
uint16_t current_gfxclk[MAX_GFX_CLKS];
uint16_t current_socclk[MAX_CLKS];
uint16_t current_vclk0[MAX_CLKS];
uint16_t current_dclk0[MAX_CLKS];
uint16_t current_uclk;
uint16_t padding;
};
struct gpu_metrics_v1_5 {
struct metrics_table_header common_header;
/* Temperature (Celsius) */
uint16_t temperature_hotspot;
uint16_t temperature_mem;
uint16_t temperature_vrsoc;
/* Power (Watts) */
uint16_t curr_socket_power;
/* Utilization (%) */
uint16_t average_gfx_activity;
uint16_t average_umc_activity; // memory controller
uint16_t vcn_activity[NUM_VCN];
uint16_t jpeg_activity[NUM_JPEG_ENG];
/* Energy (15.259uJ (2^-16) units) */
uint64_t energy_accumulator;
/* Driver attached timestamp (in ns) */
uint64_t system_clock_counter;
/* Throttle status */
uint32_t throttle_status;
/* Clock Lock Status. Each bit corresponds to clock instance */
uint32_t gfxclk_lock_status;
/* Link width (number of lanes) and speed (in 0.1 GT/s) */
uint16_t pcie_link_width;
uint16_t pcie_link_speed;
/* XGMI bus width and bitrate (in Gbps) */
uint16_t xgmi_link_width;
uint16_t xgmi_link_speed;
/* Utilization Accumulated (%) */
uint32_t gfx_activity_acc;
uint32_t mem_activity_acc;
/*PCIE accumulated bandwidth (GB/sec) */
uint64_t pcie_bandwidth_acc;
/*PCIE instantaneous bandwidth (GB/sec) */
uint64_t pcie_bandwidth_inst;
/* PCIE L0 to recovery state transition accumulated count */
uint64_t pcie_l0_to_recov_count_acc;
/* PCIE replay accumulated count */
uint64_t pcie_replay_count_acc;
/* PCIE replay rollover accumulated count */
uint64_t pcie_replay_rover_count_acc;
/* PCIE NAK sent accumulated count */
uint32_t pcie_nak_sent_count_acc;
/* PCIE NAK received accumulated count */
uint32_t pcie_nak_rcvd_count_acc;
/* XGMI accumulated data transfer size(KiloBytes) */
uint64_t xgmi_read_data_acc[NUM_XGMI_LINKS];
uint64_t xgmi_write_data_acc[NUM_XGMI_LINKS];
/* PMFW attached timestamp (10ns resolution) */
uint64_t firmware_timestamp;
/* Current clocks (Mhz) */
uint16_t current_gfxclk[MAX_GFX_CLKS];
uint16_t current_socclk[MAX_CLKS];
uint16_t current_vclk0[MAX_CLKS];
uint16_t current_dclk0[MAX_CLKS];
uint16_t current_uclk;
uint16_t padding;
};
/*
* gpu_metrics_v2_0 is not recommended as it's not naturally aligned.
* Use gpu_metrics_v2_1 or later instead.
*/
struct gpu_metrics_v2_0 {
struct metrics_table_header common_header;
/* Driver attached timestamp (in ns) */
uint64_t system_clock_counter;
/* Temperature */
uint16_t temperature_gfx; // gfx temperature on APUs
uint16_t temperature_soc; // soc temperature on APUs
uint16_t temperature_core[8]; // CPU core temperature on APUs
uint16_t temperature_l3[2];
/* Utilization */
uint16_t average_gfx_activity;
uint16_t average_mm_activity; // UVD or VCN
/* Power/Energy */
uint16_t average_socket_power; // dGPU + APU power on A + A platform
uint16_t average_cpu_power;
uint16_t average_soc_power;
uint16_t average_gfx_power;
uint16_t average_core_power[8]; // CPU core power on APUs
/* Average clocks */
uint16_t average_gfxclk_frequency;
uint16_t average_socclk_frequency;
uint16_t average_uclk_frequency;
uint16_t average_fclk_frequency;
uint16_t average_vclk_frequency;
uint16_t average_dclk_frequency;
/* Current clocks */
uint16_t current_gfxclk;
uint16_t current_socclk;
uint16_t current_uclk;
uint16_t current_fclk;
uint16_t current_vclk;
uint16_t current_dclk;
uint16_t current_coreclk[8]; // CPU core clocks
uint16_t current_l3clk[2];
/* Throttle status */
uint32_t throttle_status;
/* Fans */
uint16_t fan_pwm;
uint16_t padding;
};
struct gpu_metrics_v2_1 {
struct metrics_table_header common_header;
/* Temperature */
uint16_t temperature_gfx; // gfx temperature on APUs
uint16_t temperature_soc; // soc temperature on APUs
uint16_t temperature_core[8]; // CPU core temperature on APUs
uint16_t temperature_l3[2];
/* Utilization */
uint16_t average_gfx_activity;
uint16_t average_mm_activity; // UVD or VCN
/* Driver attached timestamp (in ns) */
uint64_t system_clock_counter;
/* Power/Energy */
uint16_t average_socket_power; // dGPU + APU power on A + A platform
uint16_t average_cpu_power;
uint16_t average_soc_power;
uint16_t average_gfx_power;
uint16_t average_core_power[8]; // CPU core power on APUs
/* Average clocks */
uint16_t average_gfxclk_frequency;
uint16_t average_socclk_frequency;
uint16_t average_uclk_frequency;
uint16_t average_fclk_frequency;
uint16_t average_vclk_frequency;
uint16_t average_dclk_frequency;
/* Current clocks */
uint16_t current_gfxclk;
uint16_t current_socclk;
uint16_t current_uclk;
uint16_t current_fclk;
uint16_t current_vclk;
uint16_t current_dclk;
uint16_t current_coreclk[8]; // CPU core clocks
uint16_t current_l3clk[2];
/* Throttle status */
uint32_t throttle_status;
/* Fans */
uint16_t fan_pwm;
uint16_t padding[3];
};
struct gpu_metrics_v2_2 {
struct metrics_table_header common_header;
/* Temperature */
uint16_t temperature_gfx; // gfx temperature on APUs
uint16_t temperature_soc; // soc temperature on APUs
uint16_t temperature_core[8]; // CPU core temperature on APUs
uint16_t temperature_l3[2];
/* Utilization */
uint16_t average_gfx_activity;
uint16_t average_mm_activity; // UVD or VCN
/* Driver attached timestamp (in ns) */
uint64_t system_clock_counter;
/* Power/Energy */
uint16_t average_socket_power; // dGPU + APU power on A + A platform
uint16_t average_cpu_power;
uint16_t average_soc_power;
uint16_t average_gfx_power;
uint16_t average_core_power[8]; // CPU core power on APUs
/* Average clocks */
uint16_t average_gfxclk_frequency;
uint16_t average_socclk_frequency;
uint16_t average_uclk_frequency;
uint16_t average_fclk_frequency;
uint16_t average_vclk_frequency;
uint16_t average_dclk_frequency;
/* Current clocks */
uint16_t current_gfxclk;
uint16_t current_socclk;
uint16_t current_uclk;
uint16_t current_fclk;
uint16_t current_vclk;
uint16_t current_dclk;
uint16_t current_coreclk[8]; // CPU core clocks
uint16_t current_l3clk[2];
/* Throttle status (ASIC dependent) */
uint32_t throttle_status;
/* Fans */
uint16_t fan_pwm;
uint16_t padding[3];
/* Throttle status (ASIC independent) */
uint64_t indep_throttle_status;
};
struct gpu_metrics_v2_3 {
struct metrics_table_header common_header;
/* Temperature */
uint16_t temperature_gfx; // gfx temperature on APUs
uint16_t temperature_soc; // soc temperature on APUs
uint16_t temperature_core[8]; // CPU core temperature on APUs
uint16_t temperature_l3[2];
/* Utilization */
uint16_t average_gfx_activity;
uint16_t average_mm_activity; // UVD or VCN
/* Driver attached timestamp (in ns) */
uint64_t system_clock_counter;
/* Power/Energy */
uint16_t average_socket_power; // dGPU + APU power on A + A platform
uint16_t average_cpu_power;
uint16_t average_soc_power;
uint16_t average_gfx_power;
uint16_t average_core_power[8]; // CPU core power on APUs
/* Average clocks */
uint16_t average_gfxclk_frequency;
uint16_t average_socclk_frequency;
uint16_t average_uclk_frequency;
uint16_t average_fclk_frequency;
uint16_t average_vclk_frequency;
uint16_t average_dclk_frequency;
/* Current clocks */
uint16_t current_gfxclk;
uint16_t current_socclk;
uint16_t current_uclk;
uint16_t current_fclk;
uint16_t current_vclk;
uint16_t current_dclk;
uint16_t current_coreclk[8]; // CPU core clocks
uint16_t current_l3clk[2];
/* Throttle status (ASIC dependent) */
uint32_t throttle_status;
/* Fans */
uint16_t fan_pwm;
uint16_t padding[3];
/* Throttle status (ASIC independent) */
uint64_t indep_throttle_status;
/* Average Temperature */
uint16_t average_temperature_gfx; // average gfx temperature on APUs
uint16_t average_temperature_soc; // average soc temperature on APUs
uint16_t average_temperature_core[8]; // average CPU core temperature on APUs
uint16_t average_temperature_l3[2];
};
struct gpu_metrics_v2_4 {
struct metrics_table_header common_header;
/* Temperature (unit: centi-Celsius) */
uint16_t temperature_gfx;
uint16_t temperature_soc;
uint16_t temperature_core[8];
uint16_t temperature_l3[2];
/* Utilization (unit: centi) */
uint16_t average_gfx_activity;
uint16_t average_mm_activity;
/* Driver attached timestamp (in ns) */
uint64_t system_clock_counter;
/* Power/Energy (unit: mW) */
uint16_t average_socket_power;
uint16_t average_cpu_power;
uint16_t average_soc_power;
uint16_t average_gfx_power;
uint16_t average_core_power[8];
/* Average clocks (unit: MHz) */
uint16_t average_gfxclk_frequency;
uint16_t average_socclk_frequency;
uint16_t average_uclk_frequency;
uint16_t average_fclk_frequency;
uint16_t average_vclk_frequency;
uint16_t average_dclk_frequency;
/* Current clocks (unit: MHz) */
uint16_t current_gfxclk;
uint16_t current_socclk;
uint16_t current_uclk;
uint16_t current_fclk;
uint16_t current_vclk;
uint16_t current_dclk;
uint16_t current_coreclk[8];
uint16_t current_l3clk[2];
/* Throttle status (ASIC dependent) */
uint32_t throttle_status;
/* Fans */
uint16_t fan_pwm;
uint16_t padding[3];
/* Throttle status (ASIC independent) */
uint64_t indep_throttle_status;
/* Average Temperature (unit: centi-Celsius) */
uint16_t average_temperature_gfx;
uint16_t average_temperature_soc;
uint16_t average_temperature_core[8];
uint16_t average_temperature_l3[2];
/* Power/Voltage (unit: mV) */
uint16_t average_cpu_voltage;
uint16_t average_soc_voltage;
uint16_t average_gfx_voltage;
/* Power/Current (unit: mA) */
uint16_t average_cpu_current;
uint16_t average_soc_current;
uint16_t average_gfx_current;
};
struct gpu_metrics_v3_0 {
struct metrics_table_header common_header;
/* Temperature */
/* gfx temperature on APUs */
uint16_t temperature_gfx;
/* soc temperature on APUs */
uint16_t temperature_soc;
/* CPU core temperature on APUs */
uint16_t temperature_core[16];
/* skin temperature on APUs */
uint16_t temperature_skin;
/* Utilization */
/* time filtered GFX busy % [0-100] */
uint16_t average_gfx_activity;
/* time filtered VCN busy % [0-100] */
uint16_t average_vcn_activity;
/* time filtered IPU per-column busy % [0-100] */
uint16_t average_ipu_activity[8];
/* time filtered per-core C0 residency % [0-100]*/
uint16_t average_core_c0_activity[16];
/* time filtered DRAM read bandwidth [MB/sec] */
uint16_t average_dram_reads;
/* time filtered DRAM write bandwidth [MB/sec] */
uint16_t average_dram_writes;
/* time filtered IPU read bandwidth [MB/sec] */
uint16_t average_ipu_reads;
/* time filtered IPU write bandwidth [MB/sec] */
uint16_t average_ipu_writes;
/* Driver attached timestamp (in ns) */
uint64_t system_clock_counter;
/* Power/Energy */
/* time filtered power used for PPT/STAPM [APU+dGPU] [mW] */
uint32_t average_socket_power;
/* time filtered IPU power [mW] */
uint16_t average_ipu_power;
/* time filtered APU power [mW] */
uint32_t average_apu_power;
/* time filtered GFX power [mW] */
uint32_t average_gfx_power;
/* time filtered dGPU power [mW] */
uint32_t average_dgpu_power;
/* time filtered sum of core power across all cores in the socket [mW] */
uint32_t average_all_core_power;
/* calculated core power [mW] */
uint16_t average_core_power[16];
/* time filtered total system power [mW] */
uint16_t average_sys_power;
/* maximum IRM defined STAPM power limit [mW] */
uint16_t stapm_power_limit;
/* time filtered STAPM power limit [mW] */
uint16_t current_stapm_power_limit;
/* time filtered clocks [MHz] */
uint16_t average_gfxclk_frequency;
uint16_t average_socclk_frequency;
uint16_t average_vpeclk_frequency;
uint16_t average_ipuclk_frequency;
uint16_t average_fclk_frequency;
uint16_t average_vclk_frequency;
uint16_t average_uclk_frequency;
uint16_t average_mpipu_frequency;
/* Current clocks */
/* target core frequency [MHz] */
uint16_t current_coreclk[16];
/* CCLK frequency limit enforced on classic cores [MHz] */
uint16_t current_core_maxfreq;
/* GFXCLK frequency limit enforced on GFX [MHz] */
uint16_t current_gfx_maxfreq;
/* Throttle Residency (ASIC dependent) */
uint32_t throttle_residency_prochot;
uint32_t throttle_residency_spl;
uint32_t throttle_residency_fppt;
uint32_t throttle_residency_sppt;
uint32_t throttle_residency_thm_core;
uint32_t throttle_residency_thm_gfx;
uint32_t throttle_residency_thm_soc;
/* Metrics table alpha filter time constant [us] */
uint32_t time_filter_alphavalue;
};
} // namespace gpu

View File

@@ -6,100 +6,7 @@ have a gpu_t getGpu(std::string path, bool hasMetrics) function
maybe have a read pp_table function
MAYBE PASS A POINTER TO SENSORS/SENSORS->GPU TO FUNCS
general order of operation
1. [main] get hwmon path from the detectGpuHwmon func
2. [main] check if we have gpu_metrics present and set hasMetrics accordingly
3. [main, loop] keep calling getGpu with hasMetrics
3. [gpu] getGpu called, parses whatever metrics we read from sysfs, then checks if hasMetrics == true
- if true, reads file at (hwmon + REL_METRICS_PATH) into buf
- reads first 4 bytes into GpuMetricsHeader_t with reinterpret_cast
- parses them for format and content version
- skips first 4 bytes of the buf and reinterpret_casts the rest into a correct gpu_metrics type (switch case?)
- populates gpu_t with values from gpu_metrics
- if false, reads the rest of relevant metrics from sysfs
- returns gpu_t
*/
struct [[gnu::packed]] GpuMetrics_v1_1_t {
uint16_t temperature_edge;
uint16_t temperature_hotspot;
uint16_t temperature_mem;
uint16_t temperature_vrgfx;
uint16_t temperature_vrsoc;
uint16_t temperature_vrmem;
uint16_t average_gfx_activity;
uint16_t average_umc_activity;
uint16_t average_mm_activity;
uint16_t average_socket_power;
uint64_t energy_accumulator;
uint64_t system_clock_counter;
uint16_t average_gfxclk_frequency;
uint16_t average_socclk_frequency;
uint16_t average_uclk_frequency;
uint16_t average_vclk0_frequency;
uint16_t average_dclk0_frequency;
uint16_t average_vclk1_frequency;
uint16_t average_dclk1_frequency;
uint16_t current_gfxclk;
uint16_t current_socclk;
uint16_t current_uclk;
uint16_t current_vclk0;
uint16_t current_dclk0;
uint16_t current_vclk1;
uint16_t current_dclk1;
uint32_t throttle_status;
uint16_t current_fan_speed;
uint16_t pcie_link_width;
uint16_t pcie_link_speed;
uint16_t padding;
uint32_t gfx_activity_acc;
uint32_t mem_activity_acc;
uint16_t temperature_hbm;
};
struct [[gnu::packed]] GpuMetrics_v1_3_t {
uint16_t temperature_edge;
uint16_t temperature_hotspot;
uint16_t temperature_mem;
uint16_t temperature_vrgfx;
uint16_t temperature_vrsoc;
uint16_t temperature_vrmem;
uint16_t average_gfx_activity;
uint16_t average_umc_activity;
uint16_t average_mm_activity;
uint16_t average_socket_power;
uint64_t energy_accumulator;
uint64_t system_clock_counter;
uint16_t average_gfxclk_frequency;
uint16_t average_socclk_frequency;
uint16_t average_uclk_frequency;
uint16_t average_vclk0_frequency;
uint16_t average_dclk0_frequency;
uint16_t average_vclk1_frequency;
uint16_t average_dclk1_frequency;
uint16_t current_gfxclk;
uint16_t current_socclk;
uint16_t current_uclk;
uint16_t current_vclk0;
uint16_t current_dclk0;
uint16_t current_vclk1;
uint16_t current_dclk1;
uint32_t throttle_status;
uint16_t current_fan_speed;
uint16_t pcie_link_width;
uint16_t pcie_link_speed;
uint16_t padding;
uint32_t gfx_activity_acc;
uint32_t mem_activity_acc;
uint16_t temperature_hbm;
uint64_t firmware_timestamp;
uint16_t voltage_soc;
uint16_t voltage_gfx;
uint16_t voltage_mem;
uint8_t padding1;
};
*/
std::string detectGpuHwmon(std::string pci) {
std::string path = getFirstDir("/sys/bus/pci/devices/" + pci + "/hwmon");
@@ -107,87 +14,60 @@ std::string detectGpuHwmon(std::string pci) {
return path;
}
GpuMetricsHeader_t getGpuMetricsHeader(std::string path) {
GpuMetricsHeader_t header;
std::ifstream f(path, std::ios::binary);
if (f.good()) {
f.read(reinterpret_cast<char *>(&header), sizeof(header));
std::println("[GpuMetrics] header at path {} read, GpuMetrics_v{}_{}, size {}", path, header.format_revision, header.content_revision, header.structure_size);
f.close();
} else {
std::println("[GpuMetrics] error reading header at path {} (wrong card # ?)", path); // should be err
bool checkForMetrics(std::string hwmon) {
if (FILE* file = fopen((hwmon + REL_METRICS_PATH).c_str(), "r")) {
fclose(file);
std::println("[GpuMetrics] found metrics file");
return true;
}
return header;
return false;
}
/* will return empty metric if fails */
auto getGpuMetrics(GpuMetricsHeader_t h, std::string path) {
GpuMetrics_v1_3_t metrics;
// void* raw_data;
uint8_t rev = h.format_revision * 10 + h.content_revision;
// const auto* metrics = reinterpret_cast<const GpuMetrics_v1_3_t*>(raw_data); // raw data is actual metrics read from disk
switch (rev) {
case 13: {
std::ifstream f(path, std::ios::binary);
if (f.good()) {
f.ignore(sizeof(h)); // skip header
f.read(reinterpret_cast<char *>(&metrics), sizeof(metrics));
f.close();
}
} break;
}
return metrics;
}
// clean abstraction of gpu_metrics + extra metrics from fs, works with rx7800xt
gpu_t getGpu(GpuMetricsHeader_t header, std::string hw) {
gpu_t getGpuFromMetrics(std::string hwmon) {
gpu_t gpu;
uint8_t hwmon = 4;
char raw_metrics[MAX_METRICS_LENGTH];
if(!readFile2(hwmon + REL_METRICS_PATH, raw_metrics, sizeof(raw_metrics))) return gpu; // return empty struct if cant read metrics
auto header = reinterpret_cast<gpu::metrics_table_header*>(raw_metrics);
// these are always read from fs
gpu.fan_speed = std::stol(readFile(hw + "/hwmon/hwmon" + std::to_string(hwmon) + "/fan1_input"));
gpu.vcore = std::stol(readFile(hw + "/hwmon/hwmon" + std::to_string(hwmon) + "/in0_input")) / 1000.0;
gpu.power_cap = std::stol(readFile(hw + "/hwmon/hwmon" + std::to_string(hwmon) + "/power1_cap", 3));
gpu.power_max = std::stol(readFile(hw + "/hwmon/hwmon" + std::to_string(hwmon) + "/power1_cap_max", 3));
gpu.fan_pwm = std::stoi(readFile(hwmon + "/pwm1", 4)) * 100 / 256; // not super useful
gpu.vram_used = std::stoul(readFile(hw + "/mem_info_vram_used"));
gpu.vram_total = std::stoul(readFile(hw + "/mem_info_vram_total"));
switch (header->format_revision * 10 + header->content_revision) {
auto metrics = getGpuMetrics(header, hw + "/gpu_metrics");
/* rx7800xt */
case 13: {
auto metrics = reinterpret_cast<gpu::gpu_metrics_v1_3*>(raw_metrics);
gpu.core_clock = metrics->average_vclk1_frequency; // why not gfxclock?
gpu.mem_clock = metrics->average_gfxclk_frequency; // why gfxclock? min mem clock seems to be 96mhz, this is probably including time sleeping
gpu.core_usage = metrics->average_gfx_activity;
gpu.media_usage = metrics->average_mm_activity;
gpu.umc_usage = metrics->average_umc_activity;
gpu.edge_temp = metrics->temperature_edge;
gpu.hotspot_temp = metrics->temperature_hotspot;
gpu.mem_temp = metrics->temperature_mem;
gpu.gfx_vrm_temp = metrics->temperature_vrgfx;
gpu.soc_vrm_temp = metrics->temperature_vrsoc;
gpu.mem_vrm_temp = metrics->temperature_vrmem;
gpu.power_avg = metrics->average_socket_power;
break;
}
// check if metrics valid, if not use fs
if (header.structure_size != 0) {
gpu.core_clock = metrics.average_vclk1_frequency; // why not gfxclock?
gpu.mem_clock = metrics.average_gfxclk_frequency; // why gfxclock? min mem clock seems to be 96mhz, this is probably including time sleeping
gpu.core_usage = metrics.average_gfx_activity;
gpu.media_usage = metrics.average_mm_activity;
gpu.umc_usage = metrics.average_umc_activity;
gpu.edge_temp = metrics.temperature_edge;
gpu.hotspot_temp = metrics.temperature_hotspot;
gpu.mem_temp = metrics.temperature_mem;
gpu.gfx_vrm_temp = metrics.temperature_vrgfx;
gpu.soc_vrm_temp = metrics.temperature_vrsoc;
gpu.mem_vrm_temp = metrics.temperature_vrmem;
gpu.power_avg = metrics.average_socket_power;
} else {
gpu.core_clock = std::stoll(readFile(hw + "/hwmon/hwmon" + std::to_string(hwmon) + "/freq1_input", 16)) / 1000000;
gpu.mem_clock = std::stoll(readFile(hw + "/hwmon/hwmon" + std::to_string(hwmon) + "/freq2_input", 16)) / 1000000;
gpu.vcore = std::stod(readFile(hw + "/hwmon/hwmon" + std::to_string(hwmon) + "/in0_input", 8)) / 1000.0;
gpu.power_avg = std::stol(readFile(hw + "/hwmon/hwmon" + std::to_string(hwmon) + "/power1_input", 3));
gpu.edge_temp = std::stol(readFile(hw + "/hwmon/hwmon" + std::to_string(hwmon) + "/temp1_input", 2));
gpu.core_usage = std::stoi(readFile(hw + "/gpu_busy_percent"));
/* ryzen 5 5600g */
case 22: {
auto metrics = reinterpret_cast<gpu::gpu_metrics_v2_2*>(raw_metrics);
gpu.edge_temp = metrics->temperature_gfx / 100;
gpu.power_avg = metrics->average_gfx_power;
gpu.core_usage = metrics->average_gfx_activity;
break;
}
/* werid hardware i probably dont like */
default: {
std::println("[GpuMetrics] Unsupported gpu_metrics_v{}_{}", header->format_revision, header->content_revision);
break;
}
}
if (gpu.fan_speed > 9999)
gpu.fan_speed = 9999;
return gpu;
}
gpu_t getGpu(std::string hwmon, bool hasMetrics) {
gpu_t getGpuFromFs(std::string hwmon) {
gpu_t gpu;
// these are always read from fs
@@ -195,21 +75,23 @@ gpu_t getGpu(std::string hwmon, bool hasMetrics) {
gpu.vcore = std::stol(readFile(hwmon + "/in0_input", 4)) / 1000.0;
gpu.power_cap = std::stol(readFile(hwmon + "/power1_cap", 16)) / 1000000;
// gpu.power_max = std::stol(readFile(hwmon + "/power1_cap_max", 16)) / 1000000;
gpu.fan_pwm = std::stoi(readFile(hwmon + "/pwm1", 4)) * 100 / 256;
gpu.fan_pwm = std::stoi(readFile(hwmon + "/pwm1", 4)) * 100 / 256;
gpu.vram_used = std::stoul(readFile(hwmon + "/../../mem_info_vram_used", 16));
// gpu.vram_total = std::stoul(readFile(hwmon + "/../../mem_info_vram_total", 16));
// these also exist in gpu_metrics?
if (!hasMetrics) {
gpu.core_clock = std::stoll(readFile(hwmon + "/freq1_input", 16)) / 1000000;
gpu.mem_clock = std::stoll(readFile(hwmon + "/freq2_input", 16)) / 1000000;
gpu.power_avg = std::stol(readFile(hwmon + "/power1_input", 16)) / 1000000;
gpu.edge_temp = std::stol(readFile(hwmon + "/temp1_input", 2));
gpu.core_usage = std::stoi(readFile(hwmon + "/../../gpu_busy_percent"));
}
if (gpu.fan_speed > 9999)
gpu.fan_speed = 9999;
gpu.core_clock = std::stoll(readFile(hwmon + "/freq1_input", 16)) / 1000000;
gpu.mem_clock = std::stoll(readFile(hwmon + "/freq2_input", 16)) / 1000000;
gpu.power_avg = std::stol(readFile(hwmon + "/power1_input", 16)) / 1000000;
gpu.edge_temp = std::stol(readFile(hwmon + "/temp1_input", 2));
gpu.core_usage = std::stoi(readFile(hwmon + "/../../gpu_busy_percent"));
return gpu;
}
}
gpu_t getGpu(std::string hwmon, bool hasMetrics) {
if (hasMetrics) {
return getGpuFromMetrics(hwmon);
} else {
return getGpuFromFs(hwmon);
}
}