summaryrefslogtreecommitdiff
path: root/benchmarks
diff options
context:
space:
mode:
authorTvrtko Ursulin <tvrtko.ursulin@intel.com>2017-05-23 12:55:09 +0100
committerTvrtko Ursulin <tvrtko.ursulin@intel.com>2017-11-22 11:19:23 +0000
commitb7f720e3d99bca8186a69d8fd50137aa30f9a4cc (patch)
treeedf89a45d5123379b0d0108030e411e1e7666f31 /benchmarks
parent20d89b417e0bceb79cd80456838b1e91662d445e (diff)
gem_wsim: Busy stats balancers
Add busy and busy-avg balancers which make balancing decisions by looking at engine busyness via the i915 PMU. And thus are able to make decisions on the actual instantaneous load of the system, and not use metrics that lag behind by a batch or two. In doing so, each client should be able to greedily maximise their own usage of the system, leading to improved load balancing even in the face of other uncooperative clients. On the other hand, we are only using the instantaneous load without coupling in the predictive factor for dispatch and execution length. v2: * Commit text. (Chris Wilson) * Rename get_stats to get_pmu_stats. (Chris Wilson) * Fix PMU readout in VCS remap mode. v3: * Integrated Petri's meson build recipe. Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Cc: Petri Latvala <petri.latvala@intel.com>
Diffstat (limited to 'benchmarks')
-rw-r--r--benchmarks/Makefile.am2
-rw-r--r--benchmarks/gem_wsim.c142
-rw-r--r--benchmarks/meson.build7
3 files changed, 149 insertions, 2 deletions
diff --git a/benchmarks/Makefile.am b/benchmarks/Makefile.am
index 9f2671be..4b461a02 100644
--- a/benchmarks/Makefile.am
+++ b/benchmarks/Makefile.am
@@ -25,7 +25,7 @@ gem_latency_CFLAGS = $(AM_CFLAGS) $(THREAD_CFLAGS)
gem_latency_LDADD = $(LDADD) -lpthread
gem_syslatency_CFLAGS = $(AM_CFLAGS) $(THREAD_CFLAGS)
gem_syslatency_LDADD = $(LDADD) -lpthread -lrt
-gem_wsim_LDADD = $(LDADD) -lpthread
+gem_wsim_LDADD = $(LDADD) $(top_builddir)/lib/libigt_perf.la -lpthread
EXTRA_DIST= \
README \
diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
index 063f3ca3..c15dc365 100644
--- a/benchmarks/gem_wsim.c
+++ b/benchmarks/gem_wsim.c
@@ -50,6 +50,7 @@
#include "intel_io.h"
#include "igt_aux.h"
#include "igt_rand.h"
+#include "igt_perf.h"
#include "sw_sync.h"
#include "ewma.h"
@@ -188,6 +189,16 @@ struct workload
uint32_t last[NUM_ENGINES];
} rt;
};
+
+ struct busy_balancer {
+ int fd;
+ bool first;
+ unsigned int num_engines;
+ unsigned int engine_map[5];
+ uint64_t t_prev;
+ uint64_t prev[5];
+ double busy[5];
+ } busy_balancer;
};
static const unsigned int nop_calibration_us = 1000;
@@ -993,6 +1004,8 @@ struct workload_balancer {
unsigned int flags;
unsigned int min_gen;
+ int (*init)(const struct workload_balancer *balancer,
+ struct workload *wrk);
unsigned int (*get_qd)(const struct workload_balancer *balancer,
struct workload *wrk,
enum intel_engine_id engine);
@@ -1242,6 +1255,108 @@ context_balance(const struct workload_balancer *balancer,
return get_vcs_engine(wrk->ctx_list[w->context].static_vcs);
}
+static unsigned int
+get_engine_busy(const struct workload_balancer *balancer,
+ struct workload *wrk, enum intel_engine_id engine)
+{
+ struct busy_balancer *bb = &wrk->busy_balancer;
+
+ if (engine == VCS2 && (wrk->flags & VCS2REMAP))
+ engine = BCS;
+
+ return bb->busy[bb->engine_map[engine]];
+}
+
+static void
+get_pmu_stats(const struct workload_balancer *b, struct workload *wrk)
+{
+ struct busy_balancer *bb = &wrk->busy_balancer;
+ uint64_t val[7];
+ unsigned int i;
+
+ igt_assert_eq(read(bb->fd, val, sizeof(val)),
+ (2 + bb->num_engines) * sizeof(uint64_t));
+
+ if (!bb->first) {
+ for (i = 0; i < bb->num_engines; i++) {
+ double d;
+
+ d = (val[2 + i] - bb->prev[i]) * 100;
+ d /= val[1] - bb->t_prev;
+ bb->busy[i] = d;
+ }
+ }
+
+ for (i = 0; i < bb->num_engines; i++)
+ bb->prev[i] = val[2 + i];
+
+ bb->t_prev = val[1];
+ bb->first = false;
+}
+
+static enum intel_engine_id
+busy_avg_balance(const struct workload_balancer *balancer,
+ struct workload *wrk, struct w_step *w)
+{
+ get_pmu_stats(balancer, wrk);
+
+ return qdavg_balance(balancer, wrk, w);
+}
+
+static enum intel_engine_id
+busy_balance(const struct workload_balancer *balancer,
+ struct workload *wrk, struct w_step *w)
+{
+ get_pmu_stats(balancer, wrk);
+
+ return qd_balance(balancer, wrk, w);
+}
+
+static int
+busy_init(const struct workload_balancer *balancer, struct workload *wrk)
+{
+ struct busy_balancer *bb = &wrk->busy_balancer;
+ struct engine_desc {
+ unsigned class, inst;
+ enum intel_engine_id id;
+ } *d, engines[] = {
+ { I915_ENGINE_CLASS_RENDER, 0, RCS },
+ { I915_ENGINE_CLASS_COPY, 0, BCS },
+ { I915_ENGINE_CLASS_VIDEO, 0, VCS1 },
+ { I915_ENGINE_CLASS_VIDEO, 1, VCS2 },
+ { I915_ENGINE_CLASS_VIDEO_ENHANCE, 0, VECS },
+ { 0, 0, VCS }
+ };
+
+ bb->num_engines = 0;
+ bb->first = true;
+ bb->fd = -1;
+
+ for (d = &engines[0]; d->id != VCS; d++) {
+ int pfd;
+
+ pfd = perf_i915_open_group(I915_PMU_ENGINE_BUSY(d->class,
+ d->inst),
+ bb->fd);
+ if (pfd < 0) {
+ if (d->id != VCS2)
+ return -(10 + bb->num_engines);
+ else
+ continue;
+ }
+
+ if (bb->num_engines == 0)
+ bb->fd = pfd;
+
+ bb->engine_map[d->id] = bb->num_engines++;
+ }
+
+ if (bb->num_engines < 5 && !(wrk->flags & VCS2REMAP))
+ return -1;
+
+ return 0;
+}
+
static const struct workload_balancer all_balancers[] = {
{
.id = 0,
@@ -1315,6 +1430,22 @@ static const struct workload_balancer all_balancers[] = {
.desc = "Static round-robin VCS assignment at context creation.",
.balance = context_balance,
},
+ {
+ .id = 9,
+ .name = "busy",
+ .desc = "Engine busyness based balancing.",
+ .init = busy_init,
+ .get_qd = get_engine_busy,
+ .balance = busy_balance,
+ },
+ {
+ .id = 10,
+ .name = "busy-avg",
+ .desc = "Average engine busyness based balancing.",
+ .init = busy_init,
+ .get_qd = get_engine_busy,
+ .balance = busy_avg_balance,
+ },
};
static unsigned int
@@ -2226,6 +2357,17 @@ int main(int argc, char **argv)
(verbose > 0 && master_workload == i);
prepare_workload(i, w[i], flags_);
+
+ if (balancer && balancer->init) {
+ int ret = balancer->init(balancer, w[i]);
+ if (ret) {
+ if (verbose)
+ fprintf(stderr,
+ "Failed to initialize balancing! (%u=%d)\n",
+ i, ret);
+ return 1;
+ }
+ }
}
gem_quiescent_gpu(fd);
diff --git a/benchmarks/meson.build b/benchmarks/meson.build
index 9ab738f7..fa7f0764 100644
--- a/benchmarks/meson.build
+++ b/benchmarks/meson.build
@@ -31,6 +31,11 @@ endif
foreach prog : benchmark_progs
# FIXME meson doesn't like binaries with the same name
# meanwhile just suffix with _bench
+ link = []
+ if prog == 'gem_wsim'
+ link += lib_igt_perf
+ endif
executable(prog + '_bench', prog + '.c',
- dependencies : test_deps)
+ link_with : link,
+ dependencies : test_deps)
endforeach