Skip to content

Commit 816b4de

Browse files
17314642flightlessmango
authored andcommitted
gpu_fdinfo: add power usage for intel gpu via hwmon
1 parent 4247170 commit 816b4de

File tree

3 files changed

+52
-3
lines changed

3 files changed

+52
-3
lines changed

src/gpu.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,10 @@ class GPU {
3838
// For now we're only accepting one of these modules at once
3939
// Might be possible that multiple can exist on a system in the future?
4040
if (vendor_id == 0x8086)
41-
fdinfo = std::make_unique<GPU_fdinfo>("i915");
41+
fdinfo = std::make_unique<GPU_fdinfo>("i915", pci_dev);
4242

4343
if (vendor_id == 0x5143)
44-
fdinfo = std::make_unique<GPU_fdinfo>("msm");
44+
fdinfo = std::make_unique<GPU_fdinfo>("msm", pci_dev);
4545
}
4646

4747
gpu_metrics get_metrics() {

src/gpu_fdinfo.cpp

+41
Original file line numberDiff line numberDiff line change
@@ -108,30 +108,71 @@ float GPU_fdinfo::get_vram_usage() {
108108
return (float)total_val / 1024 / 1024;
109109
}
110110

111+
void GPU_fdinfo::find_intel_hwmon() {
112+
std::string device = "/sys/bus/pci/devices/";
113+
device += pci_dev;
114+
device += "/hwmon";
115+
116+
auto dir_iterator = fs::directory_iterator(device);
117+
auto hwmon = dir_iterator->path().string();
118+
119+
if (hwmon.empty()) {
120+
SPDLOG_DEBUG("Intel hwmon directory is empty.");
121+
return;
122+
}
123+
124+
hwmon += "/energy1_input";
125+
126+
SPDLOG_DEBUG("Intel hwmon found: hwmon = {}", hwmon);
127+
energy_stream.open(hwmon);
128+
129+
if (!energy_stream.good())
130+
SPDLOG_DEBUG("Intel hwmon: failed to open {}", hwmon);
131+
}
132+
133+
float GPU_fdinfo::get_power_usage() {
134+
if (!energy_stream.is_open())
135+
return 0.f;
136+
137+
std::string energy_input_str;
138+
uint64_t energy_input;
139+
140+
energy_stream.seekg(0);
141+
std::getline(energy_stream, energy_input_str);
142+
energy_input = std::stoull(energy_input_str);
143+
144+
return energy_input / 1'000'000;
145+
}
146+
111147
void GPU_fdinfo::get_load() {
112148
while (!stop_thread) {
113149
std::unique_lock<std::mutex> lock(metrics_mutex);
114150
cond_var.wait(lock, [this]() { return !paused || stop_thread; });
115151

116152
static uint64_t previous_gpu_time, previous_time, now, gpu_time_now;
153+
static float power_usage_now, previous_power_usage;
117154

118155
gpu_time_now = get_gpu_time();
156+
power_usage_now = get_power_usage();
119157
now = os_time_get_nano();
120158

121159
if (gpu_time_now > previous_gpu_time &&
122160
now - previous_time > METRICS_UPDATE_PERIOD_MS * 1'000'000) {
123161
float time_since_last = now - previous_time;
124162
float gpu_since_last = gpu_time_now - previous_gpu_time;
163+
float power_usage_since_last = power_usage_now - previous_power_usage;
125164

126165
auto result = int((gpu_since_last / time_since_last) * 100);
127166
if (result > 100)
128167
result = 100;
129168

130169
metrics.load = result;
131170
metrics.memoryUsed = get_vram_usage();
171+
metrics.powerUsage = power_usage_since_last;
132172

133173
previous_gpu_time = gpu_time_now;
134174
previous_time = now;
175+
previous_power_usage = power_usage_now;
135176
}
136177
}
137178
}

src/gpu_fdinfo.h

+9-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ class GPU_fdinfo {
1818
struct gpu_metrics metrics;
1919
std::vector<FILE*> fdinfo;
2020
const char* module;
21+
const char* pci_dev;
2122
void find_fd();
23+
void find_intel_hwmon();
24+
std::ifstream energy_stream;
2225
std::thread thread;
2326
std::condition_variable cond_var;
2427
std::atomic<bool> stop_thread{false};
@@ -30,10 +33,15 @@ class GPU_fdinfo {
3033
std::string get_drm_engine_type();
3134
std::string get_drm_memory_type();
3235
float get_vram_usage();
36+
float get_power_usage();
3337

3438
public:
35-
GPU_fdinfo(const char* module) : module(module) {
39+
GPU_fdinfo(const char* module, const char* pci_dev) : module(module), pci_dev(pci_dev) {
3640
find_fd();
41+
42+
if (strstr(module, "i915"))
43+
find_intel_hwmon();
44+
3745
std::thread thread(&GPU_fdinfo::get_load, this);
3846
thread.detach();
3947
}

0 commit comments

Comments
 (0)