Skip to content

Commit dcb3704

Browse files
committed
feat(gpu_fdinfo): read Intel iGPU power from RAPL
1 parent 62f9b24 commit dcb3704

2 files changed

Lines changed: 99 additions & 0 deletions

File tree

src/gpu_fdinfo.cpp

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "gpu_fdinfo.h"
2+
#include "file_utils.h"
23

34
#ifndef TEST_ONLY
45
#include "hud_elements.h"
@@ -303,8 +304,96 @@ void GPU_fdinfo::get_current_hwmon_readings()
303304
}
304305
}
305306

307+
void GPU_fdinfo::find_intel_gpu_rapl_power()
308+
{
309+
std::string powercap = "/sys/class/powercap/";
310+
auto powercap_dirs = ls(powercap.c_str());
311+
312+
for (auto& dir : powercap_dirs) {
313+
auto path = powercap + dir;
314+
auto name = read_line(path + "/name");
315+
316+
if (name != "uncore")
317+
continue;
318+
319+
auto energy_path = path + "/energy_uj";
320+
auto energy_stream = std::ifstream(energy_path);
321+
322+
if (!energy_stream.good()) {
323+
SPDLOG_DEBUG(
324+
"powercap: Intel GPU RAPL energy is not accessible at {}",
325+
energy_path
326+
);
327+
continue;
328+
}
329+
330+
intel_gpu_rapl_energy_stream = std::move(energy_stream);
331+
332+
try {
333+
auto max_energy_range = read_line(path + "/max_energy_range_uj");
334+
if (!max_energy_range.empty())
335+
intel_gpu_rapl_max_energy_range_uj = std::stoull(max_energy_range);
336+
} catch (...) {
337+
intel_gpu_rapl_max_energy_range_uj = 0;
338+
}
339+
340+
SPDLOG_DEBUG("powercap: using Intel GPU RAPL energy at {}", energy_path);
341+
return;
342+
}
343+
}
344+
345+
bool GPU_fdinfo::read_intel_gpu_rapl_energy(uint64_t& energy_uj)
346+
{
347+
if (!intel_gpu_rapl_energy_stream.is_open())
348+
return false;
349+
350+
intel_gpu_rapl_energy_stream.clear();
351+
intel_gpu_rapl_energy_stream.seekg(0);
352+
353+
std::string energy;
354+
std::getline(intel_gpu_rapl_energy_stream, energy);
355+
356+
if (energy.empty())
357+
return false;
358+
359+
try {
360+
energy_uj = std::stoull(energy);
361+
} catch (...) {
362+
return false;
363+
}
364+
365+
return true;
366+
}
367+
368+
float GPU_fdinfo::get_intel_gpu_rapl_power_usage()
369+
{
370+
uint64_t now = 0;
371+
if (!read_intel_gpu_rapl_energy(now))
372+
return 0.f;
373+
374+
if (!intel_gpu_rapl_energy_initialized) {
375+
intel_gpu_rapl_last_energy_uj = now;
376+
intel_gpu_rapl_energy_initialized = true;
377+
return 0.f;
378+
}
379+
380+
uint64_t delta = 0;
381+
if (now >= intel_gpu_rapl_last_energy_uj) {
382+
delta = now - intel_gpu_rapl_last_energy_uj;
383+
} else if (intel_gpu_rapl_max_energy_range_uj > intel_gpu_rapl_last_energy_uj) {
384+
delta = intel_gpu_rapl_max_energy_range_uj - intel_gpu_rapl_last_energy_uj + now;
385+
}
386+
387+
intel_gpu_rapl_last_energy_uj = now;
388+
389+
return (static_cast<float>(delta) / (METRICS_UPDATE_PERIOD_MS / 1000.f)) / 1'000'000;
390+
}
391+
306392
float GPU_fdinfo::get_power_usage()
307393
{
394+
if ((module == "i915" || module == "xe") && intel_gpu_rapl_energy_stream.is_open())
395+
return get_intel_gpu_rapl_power_usage();
396+
308397
if (!hwmon_sensors["power"].filename.empty())
309398
return static_cast<float>(hwmon_sensors["power"].val) / 1'000'000;
310399

src/gpu_fdinfo.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,13 @@ class GPU_fdinfo {
9090

9191
float get_power_usage();
9292
float last_power = 0;
93+
std::ifstream intel_gpu_rapl_energy_stream;
94+
uint64_t intel_gpu_rapl_last_energy_uj = 0;
95+
uint64_t intel_gpu_rapl_max_energy_range_uj = 0;
96+
bool intel_gpu_rapl_energy_initialized = false;
97+
void find_intel_gpu_rapl_power();
98+
bool read_intel_gpu_rapl_energy(uint64_t& energy_uj);
99+
float get_intel_gpu_rapl_power_usage();
93100

94101
std::ifstream gpu_clock_stream;
95102
void find_i915_gt_dir();
@@ -208,6 +215,9 @@ class GPU_fdinfo {
208215

209216
find_hwmon_sensors();
210217

218+
if (module == "i915" || module == "xe")
219+
find_intel_gpu_rapl_power();
220+
211221
if (module == "i915")
212222
find_i915_gt_dir();
213223
else if (module == "xe")

0 commit comments

Comments
 (0)