[Intel-gfx] [PATCH i-g-t 02/10] gem_wsim: Buffer objects working sets and complex dependencies
Chris Wilson
chris at chris-wilson.co.uk
Thu Jun 18 09:22:59 UTC 2020
Quoting Tvrtko Ursulin (2020-06-18 10:05:56)
>
> On 17/06/2020 17:57, Chris Wilson wrote:
> > Quoting Tvrtko Ursulin (2020-06-17 17:01:12)
> >> From: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
> >>
> >> Add support for defining buffer object working sets and targetting them as
> >> data dependencies. For more information please see the README file.
> >>
> >> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
> >> ---
> >> benchmarks/gem_wsim.c | 453 +++++++++++++++++++++---
> >> benchmarks/wsim/README | 59 +++
> >> benchmarks/wsim/cloud-gaming-60fps.wsim | 11 +
> >> benchmarks/wsim/composited-ui.wsim | 7 +
> >> 4 files changed, 476 insertions(+), 54 deletions(-)
> >> create mode 100644 benchmarks/wsim/cloud-gaming-60fps.wsim
> >> create mode 100644 benchmarks/wsim/composited-ui.wsim
> >>
> >> diff --git a/benchmarks/gem_wsim.c b/benchmarks/gem_wsim.c
> >> index 02fe8f5a5e69..9e5bfe6a36d4 100644
> >> --- a/benchmarks/gem_wsim.c
> >> +++ b/benchmarks/gem_wsim.c
> >> @@ -88,14 +88,21 @@ enum w_type
> >> LOAD_BALANCE,
> >> BOND,
> >> TERMINATE,
> >> - SSEU
> >> + SSEU,
> >> + WORKINGSET,
> >> +};
> >> +
> >> +struct dep_entry {
> >> + int target;
> >> + bool write;
> >> + int working_set; /* -1 = step dependecy, >= 0 working set id */
> >> };
> >>
> >> struct deps
> >> {
> >> int nr;
> >> bool submit_fence;
> >> - int *list;
> >> + struct dep_entry *list;
> >> };
> >>
> >> struct w_arg {
> >> @@ -110,6 +117,14 @@ struct bond {
> >> enum intel_engine_id master;
> >> };
> >>
> >> +struct working_set {
> >> + int id;
> >> + bool shared;
> >> + unsigned int nr;
> >> + uint32_t *handles;
> >> + unsigned long *sizes;
> >> +};
> >> +
> >> struct workload;
> >>
> >> struct w_step
> >> @@ -143,6 +158,7 @@ struct w_step
> >> enum intel_engine_id bond_master;
> >> };
> >> int sseu;
> >> + struct working_set working_set;
> >> };
> >>
> >> /* Implementation details */
> >> @@ -193,6 +209,9 @@ struct workload
> >> unsigned int nr_ctxs;
> >> struct ctx *ctx_list;
> >>
> >> + struct working_set **working_sets; /* array indexed by set id */
> >> + int max_working_set_id;
> >> +
> >> int sync_timeline;
> >> uint32_t sync_seqno;
> >>
> >> @@ -281,11 +300,120 @@ print_engine_calibrations(void)
> >> printf("\n");
> >> }
> >>
> >> +static void add_dep(struct deps *deps, struct dep_entry entry)
> >> +{
> >> + deps->list = realloc(deps->list, sizeof(*deps->list) * (deps->nr + 1));
> >> + igt_assert(deps->list);
> >> +
> >> + deps->list[deps->nr++] = entry;
> >> +}
> >> +
> >> +
> >> +static int
> >> +parse_dependency(unsigned int nr_steps, struct w_step *w, char *str)
> >> +{
> >> + struct dep_entry entry = { .working_set = -1 };
> >> + bool submit_fence = false;
> >> + char *s;
> >> +
> >> + switch (str[0]) {
> >> + case '-':
> >> + if (str[1] < '0' || str[1] > '9')
> >> + return -1;
> >> +
> >> + entry.target = atoi(str);
> >> + if (entry.target > 0 || ((int)nr_steps + entry.target) < 0)
> >> + return -1;
> >
> > add_dep for N steps ago, using a handle.
> >
> >> +
> >> + add_dep(&w->data_deps, entry);
> >> +
> >> + break;
> >> + case 's':
> >> + submit_fence = true;
> >> + /* Fall-through. */
> >> + case 'f':
> >> + /* Multiple fences not yet supported. */
> >> + igt_assert_eq(w->fence_deps.nr, 0);
> >> +
> >> + entry.target = atoi(++str);
> >> + if (entry.target > 0 || ((int)nr_steps + entry.target) < 0)
> >> + return -1;
> >> +
> >> + add_dep(&w->fence_deps, entry);
> >> +
> >> + w->fence_deps.submit_fence = submit_fence;
> >
> > add_dep for N steps ago, using the out-fence from that step
> > [A post processing steps adds emit_fence to the earlier steps.]
> >
> >> + break;
> >> + case 'w':
> >> + entry.write = true;
> >
> > Got confused for a moment as I was expecting the submit_fence
> > fallthrough pattern.
> >> + /* Fall-through. */
> >> + case 'r':
> >> + /*
> >> + * [rw]N-<str>
> >> + * r1-<str> or w2-<str>, where N is working set id.
> >> + */
> >> + s = index(++str, '-');
> >> + if (!s)
> >> + return -1;
> >> +
> >> + entry.working_set = atoi(str);
> >
> > if (entry.working_set < 0)
> > return -1;
>
> Yep.
>
> >
> >> +
> >> + if (parse_working_set_deps(w->wrk, &w->data_deps, entry, ++s))
> >> + return -1;
> >
> > The new one...
> >
> >> +static int
> >> +parse_working_set_deps(struct workload *wrk,
> >> + struct deps *deps,
> >> + struct dep_entry _entry,
> >> + char *str)
> >> +{
> >> + /*
> >> + * 1 - target handle index in the specified working set.
> >> + * 2-4 - range
> >> + */
> >> + struct dep_entry entry = _entry;
> >> + char *s;
> >> +
> >> + s = index(str, '-');
> >> + if (s) {
> >> + int from, to;
> >> +
> >> + from = atoi(str);
> >> + if (from < 0)
> >> + return -1;
> >> +
> >> + to = atoi(++s);
> >> + if (to <= 0)
> >> + return -1;
> >
> > if to < from, we add nothing. Is that worth the error?
>
> Yep.
>
> >
> >> +
> >> + for (entry.target = from; entry.target <= to; entry.target++)
> >> + add_dep(deps, entry);
> >> + } else {
> >> + entry.target = atoi(str);
> >> + if (entry.target < 0)
> >> + return -1;
> >> +
> >> + add_dep(deps, entry);
> >
> >
> >> + }
> >> +
> >> + return 0;
> >> +}
> >> +
> >> + break;
> >> + default:
> >> + return -1;
> >> + };
> >> +
> >> + return 0;
> >> +}
> >> +
> >> static int
> >> parse_dependencies(unsigned int nr_steps, struct w_step *w, char *_desc)
> >> {
> >> char *desc = strdup(_desc);
> >> char *token, *tctx = NULL, *tstart = desc;
> >> + int ret = 0;
> >> +
> >> + if (!strcmp(_desc, "0"))
> >> + goto out;
> >
> > Hang on, what this special case?
>
> For no dependencies.
>
> If I move the check to parse_dependency then dependency of "0/0/0/0"
> would be silently accepted. It wouldn't be a big deal, who cares, but I
> thought it is better to be more strict.
It was just not clear at this point what is being matched, what the
meaning of 0 is.
/* 0 refers to self, a degenerate dependency */
?
-Chris
More information about the Intel-gfx
mailing list