[igt-dev] [PATCH i-g-t 2/2] intel-gpu-overlay: Show 1s, 30s and 15m GPU load

Chris Wilson chris at chris-wilson.co.uk
Tue Feb 13 10:46:10 UTC 2018


Quoting Tvrtko Ursulin (2018-02-12 19:01:58)
> From: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
> 
> Show total GPU loads in the window banner.
> 
> Engine load is defined as total of runnable and running requests on an
> engine.
> 
> Total, non-normalized, load is display. In other words if N engines are
> busy with exactly one request, the load will be shown as N.
> 
> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
> ---
>  overlay/gpu-top.c | 37 ++++++++++++++++++++++++++++++++++++-
>  overlay/gpu-top.h | 10 +++++++++-
>  overlay/overlay.c | 27 +++++++++++++++++++--------
>  3 files changed, 64 insertions(+), 10 deletions(-)
> 
> diff --git a/overlay/gpu-top.c b/overlay/gpu-top.c
> index 22e9badb22c1..ca25e998e3d7 100644
> --- a/overlay/gpu-top.c
> +++ b/overlay/gpu-top.c
> @@ -290,17 +290,35 @@ static void mmio_init(struct gpu_top *gt)
>         }
>  }
>  
> -void gpu_top_init(struct gpu_top *gt)
> +void gpu_top_init(struct gpu_top *gt, unsigned int period_us)
>  {
> +       const double period = (double)period_us / 1e6;
> +       const double load_period[NUM_LOADS] = { 1.0, 30.0, 900.0 };
> +       const char *load_names[NUM_LOADS] = { "1s", "30s", "15m" };
> +       unsigned int i;
> +
>         memset(gt, 0, sizeof(*gt));
>         gt->fd = -1;
>  
> +       for (i = 0; i < NUM_LOADS; i++) {
> +               gt->load_name[i] = load_names[i];
> +               gt->exp[i] = period / load_period[i];
> +       }
> +
>         if (perf_init(gt) == 0)
>                 return;
>  
>         mmio_init(gt);
>  }
>  
> +static double update_load(double load, double exp, double val)
> +{
> +       load *= 1.0 - exp;
> +       load += exp * val;
> +
> +       return load;
> +}
> +
>  int gpu_top_update(struct gpu_top *gt)
>  {
>         uint32_t data[1024];
> @@ -313,6 +331,8 @@ int gpu_top_update(struct gpu_top *gt)
>                 struct gpu_top_stat *s = &gt->stat[gt->count++&1];
>                 struct gpu_top_stat *d = &gt->stat[gt->count&1];
>                 uint64_t *sample, d_time;
> +               double gpu_qd = 0.0;
> +               unsigned int i;
>                 int n, m;
>  
>                 len = read(gt->fd, data, sizeof(data));
> @@ -341,6 +361,8 @@ int gpu_top_update(struct gpu_top *gt)
>  
>                 d_time = s->time - d->time;
>                 for (n = 0; n < gt->num_rings; n++) {
> +                       double qd = 0.0;
> +
>                         gt->ring[n].u.u.busy = (100 * (s->busy[n] - d->busy[n]) + d_time/2) / d_time;
>                         if (gt->have_wait)
>                                 gt->ring[n].u.u.wait = (100 * (s->wait[n] - d->wait[n]) + d_time/2) / d_time;
> @@ -353,6 +375,14 @@ int gpu_top_update(struct gpu_top *gt)
>                         if (gt->have_running)
>                                 gt->ring[n].running = (double)((s->running[n] - d->running[n])) / I915_SAMPLE_RUNNING_DIVISOR * 1e9 / d_time;
>  
> +                       qd = gt->ring[n].runnable + gt->ring[n].running;
> +                       gpu_qd += qd;
> +
> +                       for (i = 0; i < NUM_LOADS; i++)
> +                               gt->ring[n].load[i] =
> +                                       update_load(gt->ring[n].load[i],
> +                                                   gt->exp[i], qd);
> +
>                         /* in case of rounding + sampling errors, fudge */
>                         if (gt->ring[n].u.u.busy > 100)
>                                 gt->ring[n].u.u.busy = 100;
> @@ -362,6 +392,11 @@ int gpu_top_update(struct gpu_top *gt)
>                                 gt->ring[n].u.u.sema = 100;
>                 }
>  
> +               for (i = 0; i < NUM_LOADS; i++) {
> +                       gt->load[i] = update_load(gt->load[i], gt->exp[i],
> +                                                 gpu_qd);
> +                       gt->norm_load[i] = gt->load[i] / gt->num_rings;
> +               }
>                 update = 1;
>         } else {
>                 while ((len = read(gt->fd, data, sizeof(data))) > 0) {
> diff --git a/overlay/gpu-top.h b/overlay/gpu-top.h
> index cb4310c82a94..8fc617ce8492 100644
> --- a/overlay/gpu-top.h
> +++ b/overlay/gpu-top.h
> @@ -26,6 +26,7 @@
>  #define GPU_TOP_H
>  
>  #define MAX_RINGS 16
> +#define NUM_LOADS 3
>  
>  #include <stdint.h>
>  
> @@ -40,6 +41,11 @@ struct gpu_top {
>         int have_runnable;
>         int have_running;
>  
> +       double exp[NUM_LOADS];
> +       double load[NUM_LOADS];
> +       double norm_load[NUM_LOADS];
> +       const char *load_name[NUM_LOADS];
> +
>         struct gpu_top_ring {
>                 const char *name;
>                 union gpu_top_payload {
> @@ -54,6 +60,8 @@ struct gpu_top {
>                 double queued;
>                 double runnable;
>                 double running;
> +
> +               double load[NUM_LOADS];
>         } ring[MAX_RINGS];
>  
>         struct gpu_top_stat {
> @@ -69,7 +77,7 @@ struct gpu_top {
>         int count;
>  };
>  
> -void gpu_top_init(struct gpu_top *gt);
> +void gpu_top_init(struct gpu_top *gt, unsigned int period_us);
>  int gpu_top_update(struct gpu_top *gt);
>  
>  #endif /* GPU_TOP_H */
> diff --git a/overlay/overlay.c b/overlay/overlay.c
> index a639703ebcec..30f712e4415a 100644
> --- a/overlay/overlay.c
> +++ b/overlay/overlay.c
> @@ -141,7 +141,8 @@ struct overlay_context {
>  };
>  
>  static void init_gpu_top(struct overlay_context *ctx,
> -                        struct overlay_gpu_top *gt)
> +                        struct overlay_gpu_top *gt,
> +                        unsigned int period_us)
>  {
>         const double rgba[][4] = {
>                 { 1, 0.25, 0.25, 1 },
> @@ -152,7 +153,7 @@ static void init_gpu_top(struct overlay_context *ctx,
>         int n;
>  
>         cpu_top_init(&gt->cpu_top);
> -       gpu_top_init(&gt->gpu_top);
> +       gpu_top_init(&gt->gpu_top, period_us);
>  
>         chart_init(&gt->cpu, "CPU", 120);
>         chart_set_position(&gt->cpu, PAD, PAD);
> @@ -929,13 +930,13 @@ int main(int argc, char **argv)
>  
>         debugfs_init();
>  
> -       init_gpu_top(&ctx, &ctx.gpu_top);
> +       sample_period = get_sample_period(&config);
> +
> +       init_gpu_top(&ctx, &ctx.gpu_top, sample_period);
>         init_gpu_perf(&ctx, &ctx.gpu_perf);
>         init_gpu_freq(&ctx, &ctx.gpu_freq);
>         init_gem_objects(&ctx, &ctx.gem_objects);
>  
> -       sample_period = get_sample_period(&config);
> -
>         i = 0;
>         while (1) {
>                 ctx.time = time(NULL);
> @@ -951,16 +952,26 @@ int main(int argc, char **argv)
>                 show_gem_objects(&ctx, &ctx.gem_objects);
>  
>                 {
> -                       char buf[80];
> +                       struct gpu_top *gt = &ctx.gpu_top.gpu_top;
> +                       char buf[80], buf2[256];
>                         cairo_text_extents_t extents;
> +
>                         gethostname(buf, sizeof(buf));
> +                       snprintf(buf2, sizeof(buf2),
> +                                "%s; %u engines; load-avg %s %.2f, %s %.2f, %s %.2f",
> +                                buf,
> +                                gt->num_rings,
> +                                gt->load_name[0], gt->load[0],
> +                                gt->load_name[1], gt->load[1],
> +                                gt->load_name[2], gt->load[2]);

Too much text :)

"%s: %u engines, load %.2f %.2f %.2f" worksforme

diff --git a/overlay/overlay.c b/overlay/overlay.c
index 30f712e4..91f8d523 100644
--- a/overlay/overlay.c
+++ b/overlay/overlay.c
@@ -953,25 +953,27 @@ int main(int argc, char **argv)
 
                {
                        struct gpu_top *gt = &ctx.gpu_top.gpu_top;
-                       char buf[80], buf2[256];
                        cairo_text_extents_t extents;
+                       char buf[256];
 
                        gethostname(buf, sizeof(buf));
-                       snprintf(buf2, sizeof(buf2),
-                                "%s; %u engines; load-avg %s %.2f, %s %.2f, %s %.2f",
-                                buf,
-                                gt->num_rings,
-                                gt->load_name[0], gt->load[0],
-                                gt->load_name[1], gt->load[1],
-                                gt->load_name[2], gt->load[2]);
+                        if (gt->load[2] > 0) { /* gt->has_load_avg */
+                           int len = strlen(buf);
+                           snprintf(buf + len, sizeof(buf) - len,
+                                    ": %u engines, load %.2f %.2f %.2f",
+                                    gt->num_rings,
+                                    gt->load[0],
+                                    gt->load[1],
+                                    gt->load[2]);
+                        }
 
                        cairo_set_source_rgb(ctx.cr, .5, .5, .5);
                        cairo_set_font_size(ctx.cr, PAD-2);
-                       cairo_text_extents(ctx.cr, buf2, &extents);
+                       cairo_text_extents(ctx.cr, buf, &extents);
                        cairo_move_to(ctx.cr,
                                      (ctx.width-extents.width)/2.,
                                      1+extents.height);
-                       cairo_show_text(ctx.cr, buf2);
+                       cairo_show_text(ctx.cr, buf);
                }
 
                cairo_destroy(ctx.cr);


More information about the igt-dev mailing list