From: Ville Syrjala <ville.syrjala@linux.intel.com>
To: igt-dev@lists.freedesktop.org
Subject: [PATCH i-g-t 4/5] tools/power: Introduce a small power/energy measurement tool
Date: Mon, 16 Sep 2024 23:18:40 +0300 [thread overview]
Message-ID: <20240916201841.29592-5-ville.syrjala@linux.intel.com> (raw)
In-Reply-To: <20240916201841.29592-1-ville.syrjala@linux.intel.com>
From: Ville Syrjälä <ville.syrjala@linux.intel.com>
Provide a small tool for general power/energy measurements.
The tool operates as follow:
1. optionally sleep for a while to let the system settle
2. sample from number of rapl/hwmon/battery sources
3. sleep for a know amount of time
4. sample again from the same sources
5. calculate the results and report how much power/energy was used
igt_power provides the actual power/energy measurement stuff.
Sample output:
$ power -S 30 -s 30 -d /dev/dri/card0 -b 0 -r gpu -r pkg
/dev/dri/card0[gpu]: energy 17.944336 mJ, power 0.597746 mW, time 30.020000 s
battery[0]: energy 108000.000000 mJ, power 3597.585325 mW, time 30.020136 s
rapl[gpu]: energy 17.944336 mJ, power 0.597824 mW, time 30.016083 s
rapl[pkg]: energy 24139.099121 mJ, power 804.205461 mW, time 30.016085 s
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
tools/meson.build | 1 +
tools/power.c | 179 ++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 180 insertions(+)
create mode 100644 tools/power.c
diff --git a/tools/meson.build b/tools/meson.build
index df26c4b95e3f..48c9a4b5089e 100644
--- a/tools/meson.build
+++ b/tools/meson.build
@@ -43,6 +43,7 @@ tools_progs = [
'intel_gvtg_test',
'dpcd_reg',
'lsgpu',
+ 'power',
]
tool_deps = igt_deps
tool_deps += zlib
diff --git a/tools/power.c b/tools/power.c
new file mode 100644
index 000000000000..75c62ad39e61
--- /dev/null
+++ b/tools/power.c
@@ -0,0 +1,179 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2024 Intel Corporation
+ */
+
+#include <fcntl.h>
+#include <getopt.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "drmtest.h"
+#include "igt_power.h"
+
+struct measurement {
+ int battery_index;
+ const char *rapl_domain;
+ const char *drm_device;
+ struct power_sample pre, post;
+ struct igt_power power;
+};
+
+static bool prepare(struct measurement *m)
+{
+ if (m->battery_index >= 0) {
+ if (igt_power_bat_open(&m->power, m->battery_index)) {
+ fprintf(stderr, "Unable to open battery %d\n", m->battery_index);
+ return false;
+ }
+ }
+
+ if (m->rapl_domain) {
+ int fd = -1;
+
+ if (m->drm_device) {
+ fd = open(m->drm_device, O_RDONLY);
+ if (fd < 0) {
+ fprintf(stderr, "Unable to open drm device %s\n", m->drm_device);
+ return false;
+ }
+ }
+
+ if (igt_power_open(fd, &m->power, m->rapl_domain)) {
+ if (m->drm_device)
+ fprintf(stderr, "Unable to open hwmon/rapl for %s\n", m->drm_device);
+ else
+ fprintf(stderr, "Unable to open rapl domain %s\n", m->rapl_domain);
+ close(fd);
+ return false;
+ }
+
+ close(fd);
+ }
+
+ return true;
+}
+
+static void sample_pre(struct measurement *m)
+{
+ igt_power_get_energy(&m->power, &m->pre);
+}
+
+static void sample_post(struct measurement *m)
+{
+ igt_power_get_energy(&m->power, &m->post);
+}
+
+static void report(struct measurement *m)
+{
+ if (m->battery_index >= 0)
+ printf("battery[%d]: energy %f mJ, power %f mW, time %f s\n",
+ m->battery_index,
+ igt_power_get_mJ(&m->power, &m->pre, &m->post),
+ igt_power_get_mW(&m->power, &m->pre, &m->post),
+ igt_power_get_s(&m->pre, &m->post));
+ else
+ printf("%s[%s]: energy %f mJ, power %f mW, time %f s\n",
+ m->drm_device ?: "rapl", m->rapl_domain,
+ igt_power_get_mJ(&m->power, &m->pre, &m->post),
+ igt_power_get_mW(&m->power, &m->pre, &m->post),
+ igt_power_get_s(&m->pre, &m->post));
+
+ igt_power_close(&m->power);
+}
+
+static void __attribute__((noreturn)) usage(const char *name)
+{
+ fprintf(stderr,
+ "Usage: %s [[-d <device>][-r <domain>][-b <battery>]...][-S <seconds>][-s <seconds>]\n"
+ " -d,--drm <device>\tDRM device (eg. /dev/dri/card0)\n"
+ " -r,--rapl <domain>\trapl domain (cpu,gpu,pkg,ram)\n"
+ " -b,--battery <battery>\tbattery index\n"
+ " -S,--settle <seconds>\tsettling duration\n"
+ " -s,--sleep <seconds>\tmeasurement duration\n",
+ name);
+ exit(1);
+}
+
+int main(int argc, char *argv[])
+{
+ struct measurement measurements[8];
+ int num_measurements = 0;
+ int measurement_duration = 0;
+ int settle_duration = 0;
+
+ for (;;) {
+ static const struct option long_options[] = {
+ { .name = "drm", .has_arg = required_argument, },
+ { .name = "rapl", .has_arg = required_argument, },
+ { .name = "battery", .has_arg = required_argument, },
+ { .name = "sleep", .has_arg = required_argument, },
+ { .name = "settle", .has_arg = required_argument, },
+ {}
+ };
+
+ int opt = getopt_long(argc, argv, "d:r:b:S:s:", long_options, NULL);
+ if (opt == -1)
+ break;
+
+ switch (opt) {
+ case 'd':
+ if (num_measurements >= ARRAY_SIZE(measurements))
+ usage(argv[0]);
+ measurements[num_measurements].battery_index = -1;
+ measurements[num_measurements].rapl_domain = "gpu";
+ measurements[num_measurements].drm_device = optarg;
+ num_measurements++;
+ break;
+ case 'r':
+ if (num_measurements >= ARRAY_SIZE(measurements))
+ usage(argv[0]);
+ measurements[num_measurements].battery_index = -1;
+ measurements[num_measurements].rapl_domain = optarg;
+ measurements[num_measurements].drm_device = NULL;
+ num_measurements++;
+ break;
+ case 'b':
+ if (num_measurements >= ARRAY_SIZE(measurements))
+ usage(argv[0]);
+ measurements[num_measurements].battery_index = atoi(optarg);
+ measurements[num_measurements].rapl_domain = NULL;
+ measurements[num_measurements].drm_device = NULL;
+ num_measurements++;
+ break;
+ case 's':
+ measurement_duration = atoi(optarg);
+ break;
+ case 'S':
+ settle_duration = atoi(optarg);
+ break;
+ default:
+ usage(argv[0]);
+ break;
+ }
+ }
+
+ if (num_measurements == 0)
+ usage(argv[0]);
+
+ for (int i = 0; i < num_measurements; i++) {
+ if (!prepare(&measurements[i]))
+ usage(argv[0]);
+ }
+
+ sleep(settle_duration);
+
+ for (int i = 0; i < num_measurements; i++)
+ sample_pre(&measurements[i]);
+
+ sleep(measurement_duration);
+
+ for (int i = 0; i < num_measurements; i++)
+ sample_post(&measurements[i]);
+
+ for (int i = 0; i < num_measurements; i++)
+ report(&measurements[i]);
+
+ return 0;
+}
--
2.44.2
next prev parent reply other threads:[~2024-09-16 20:18 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-16 20:18 [PATCH i-g-t 0/5] Power/energy and display memory bandwidth measurement tools Ville Syrjala
2024-09-16 20:18 ` [PATCH i-g-t 1/5] lib/power: Allow use of rapl by specifying fd=-1 Ville Syrjala
2024-10-11 17:17 ` Kamil Konieczny
2024-10-14 16:57 ` Ville Syrjälä
2024-09-16 20:18 ` [PATCH i-g-t 2/5] igt: Use is_intel_dgfx() Ville Syrjala
2024-10-11 17:20 ` Kamil Konieczny
2024-09-16 20:18 ` [PATCH i-g-t 3/5] lib/igt_power: Add power_supply/BAT based measurement Ville Syrjala
2024-10-11 17:30 ` Kamil Konieczny
2024-10-14 17:07 ` Ville Syrjälä
2024-09-16 20:18 ` Ville Syrjala [this message]
2024-10-11 17:39 ` [PATCH i-g-t 4/5] tools/power: Introduce a small power/energy measurement tool Kamil Konieczny
2024-09-16 20:18 ` [PATCH i-g-t 5/5] tools/intel_display_bandwidth: Tool for measuring display memory bandwidth utilization Ville Syrjala
2024-10-11 17:52 ` Kamil Konieczny
2024-10-14 16:34 ` Ville Syrjälä
2025-02-26 15:39 ` Govindapillai, Vinod
2025-02-26 15:51 ` Ville Syrjälä
2025-02-26 16:23 ` Govindapillai, Vinod
2024-09-16 21:24 ` ✓ CI.xeBAT: success for Power/energy and display memory bandwidth measurement tools Patchwork
2024-09-16 21:40 ` ✓ Fi.CI.BAT: " Patchwork
2024-09-17 0:20 ` ✗ CI.xeFULL: failure " Patchwork
2024-09-17 11:05 ` ✗ Fi.CI.IGT: " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240916201841.29592-5-ville.syrjala@linux.intel.com \
--to=ville.syrjala@linux.intel.com \
--cc=igt-dev@lists.freedesktop.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox