diff options
Diffstat (limited to 'benchmarks/gem_wsim.c')
-rw-r--r-- | benchmarks/gem_wsim.c | 133 |
1 files changed, 113 insertions, 20 deletions
diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c index 47b070e2..9f690369 100644 --- a/benchmarks/gem_wsim.c +++ b/benchmarks/gem_wsim.c @@ -50,6 +50,8 @@ #include "igt_aux.h" #include "igt_rand.h" +#include "ewma.h" + enum intel_engine_id { RCS, BCS, @@ -103,6 +105,8 @@ struct w_step unsigned int mapped_len; }; +DECLARE_EWMA(uint64_t, rt, 4, 2) + struct workload { unsigned int nr_steps; @@ -127,6 +131,13 @@ struct workload struct igt_list requests[NUM_ENGINES]; unsigned int nrequest[NUM_ENGINES]; + + union { + struct rtavg { + struct ewma_rt avg[NUM_ENGINES]; + uint32_t last[NUM_ENGINES]; + } rt; + }; }; static const unsigned int nop_calibration_us = 1000; @@ -788,12 +799,31 @@ static const struct workload_balancer qd_balancer = { }; static enum intel_engine_id +__rt_select_engine(struct workload *wrk, unsigned long *qd, bool random) +{ + unsigned int n; + + qd[VCS1] >>= 10; + qd[VCS2] >>= 10; + + if (qd[VCS1] < qd[VCS2]) + n = 0; + else if (qd[VCS2] < qd[VCS1]) + n = 1; + else if (random) + n = hars_petruska_f54_1_random(&wrk->prng) & 1; + else + n = wrk->vcs_rr; + wrk->vcs_rr = n ^ 1; + + return get_vcs_engine(n); +} + +static enum intel_engine_id __rt_balance(const struct workload_balancer *balancer, struct workload *wrk, struct w_step *w, bool random) { - enum intel_engine_id engine; - long qd[NUM_ENGINES]; - unsigned int n; + unsigned long qd[NUM_ENGINES]; igt_assert(w->engine == VCS); @@ -827,22 +857,7 @@ __rt_balance(const struct workload_balancer *balancer, qd[VCS2]); #endif - qd[VCS1] >>= 10; - qd[VCS2] >>= 10; - - if (qd[VCS1] < qd[VCS2]) - n = 0; - else if (qd[VCS2] < qd[VCS1]) - n = 1; - else if (random) - n = hars_petruska_f54_1_random(&wrk->prng) & 1; - else - n = wrk->vcs_rr; - - engine = get_vcs_engine(n); - wrk->vcs_rr = n ^ 1; - - return engine; + return __rt_select_engine(wrk, qd, random); } static enum intel_engine_id @@ -870,6 +885,68 @@ static const struct workload_balancer rtr_balancer = { .balance = rtr_balance, }; +static enum intel_engine_id +rtavg_balance(const struct workload_balancer *balancer, + struct workload *wrk, struct w_step *w) +{ + unsigned long qd[NUM_ENGINES]; + + igt_assert(w->engine == VCS); + + /* Estimate the average "speed" of the most recent batches + * (finish time - submit time) + * and use that as an approximate for the total remaining time for + * all batches on that engine plus the time we expect to execute in. + * We try to keep the total remaining balanced between the engines. + */ + if (wrk->status_page[VCS_SEQNO_IDX(VCS1)] != wrk->rt.last[VCS1]) { + igt_assert((long)(wrk->status_page[2] - wrk->status_page[1]) > 0); + ewma_rt_add(&wrk->rt.avg[VCS1], + wrk->status_page[2] - wrk->status_page[1]); + wrk->rt.last[VCS1] = wrk->status_page[VCS_SEQNO_IDX(VCS1)]; + } + + qd[VCS1] = balancer->get_qd(balancer, wrk, VCS1); + wrk->qd_sum[VCS1] += qd[VCS1]; + qd[VCS1] = (qd[VCS1] + 1) * ewma_rt_read(&wrk->rt.avg[VCS1]); + +#ifdef DEBUG + printf("qd[0] = %d (%d - %d) x %ld (%d) = %ld\n", + wrk->seqno[VCS1] - wrk->status_page[0], + wrk->seqno[VCS1], wrk->status_page[0], + ewma_rt_read(&wrk->rt.avg[VCS1]), + wrk->status_page[2] - wrk->status_page[1], + qd[VCS1]); +#endif + + if (wrk->status_page[VCS_SEQNO_IDX(VCS2)] != wrk->rt.last[VCS2]) { + igt_assert((long)(wrk->status_page[2+16] - wrk->status_page[1+16]) > 0); + ewma_rt_add(&wrk->rt.avg[VCS2], + wrk->status_page[2+16] - wrk->status_page[1+16]); + wrk->rt.last[VCS2] = wrk->status_page[VCS_SEQNO_IDX(VCS2)]; + } + + qd[VCS2] = balancer->get_qd(balancer, wrk, VCS2); + wrk->qd_sum[VCS2] += qd[VCS2]; + qd[VCS2] = (qd[VCS2] + 1) * ewma_rt_read(&wrk->rt.avg[VCS2]); + +#ifdef DEBUG + printf("qd[1] = %d (%d - %d) x %ld (%d) = %ld\n", + wrk->seqno[VCS2] - wrk->status_page[16], + wrk->seqno[VCS2], wrk->status_page[16], + ewma_rt_read(&wrk->rt.avg[VCS2]), + wrk->status_page[18] - wrk->status_page[17], + qd[VCS2]); +#endif + + return __rt_select_engine(wrk, qd, false); +} + +static const struct workload_balancer rtavg_balancer = { + .get_qd = get_qd_depth, + .balance = rtavg_balance, +}; + static void update_bb_seqno(struct w_step *w, enum intel_engine_id engine, uint32_t seqno) { @@ -1277,7 +1354,7 @@ add_workload_arg(char **w_args, unsigned int nr_args, char *w_arg) static int parse_balancing_mode(char *str) { - const char *modes[] = { "rr", "qd", "rt", "rtr" }; + const char *modes[] = { "rr", "qd", "rt", "rtr" , "rtavg" }; int mode = -1; unsigned int i; @@ -1394,27 +1471,43 @@ int main(int argc, char **argv) } switch (i) { case 0: + if (!quiet) + printf("Using rr balancer\n"); balancer = &rr_balancer; flags |= BALANCE; break; case 1: + if (!quiet) + printf("Using qd balancer\n"); igt_assert(intel_gen(intel_get_drm_devid(fd)) >= 8); balancer = &qd_balancer; flags |= SEQNO | BALANCE; break; case 2: + if (!quiet) + printf("Using rt balancer\n"); igt_assert(intel_gen(intel_get_drm_devid(fd)) >= 8); balancer = &rt_balancer; flags |= SEQNO | BALANCE | RT; break; case 3: + if (!quiet) + printf("Using rtr balancer\n"); igt_assert(intel_gen(intel_get_drm_devid(fd)) >= 8); balancer = &rtr_balancer; flags |= SEQNO | BALANCE | RT; break; + case 4: + if (!quiet) + printf("Using rtavg balancer\n"); + igt_assert(intel_gen(intel_get_drm_devid(fd)) >= + 8); + balancer = &rtavg_balancer; + flags |= SEQNO | BALANCE | RT; + break; default: if (!quiet) fprintf(stderr, |