summaryrefslogtreecommitdiff
path: root/benchmarks/gem_exec_trace.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2017-03-29 18:28:09 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2017-03-29 18:28:47 +0100
commitff9c6d7225c923f7d295cf65d022aee0bc763c4a (patch)
tree3b094ce9a753a3acca9a009003e22e847844370b /benchmarks/gem_exec_trace.c
parentdc43fb985b85cf45f68a6af45b6fc92b42817f49 (diff)
benchmarks/gem_exec_trace: Randomise batch duration
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'benchmarks/gem_exec_trace.c')
-rw-r--r--benchmarks/gem_exec_trace.c70
1 files changed, 63 insertions, 7 deletions
diff --git a/benchmarks/gem_exec_trace.c b/benchmarks/gem_exec_trace.c
index 035b144b..12577649 100644
--- a/benchmarks/gem_exec_trace.c
+++ b/benchmarks/gem_exec_trace.c
@@ -91,6 +91,15 @@ struct trace_wait {
uint32_t handle;
} __attribute__((packed));
+static uint32_t hars_petruska_f54_1_random(void)
+{
+ static uint32_t state = 0x12345678;
+
+#define rol(x,k) ((x << k) | (x >> (32-k)))
+ return state = (state ^ rol (state, 5) ^ rol (state, 24)) + 0x37798849;
+#undef rol
+}
+
static double elapsed(const struct timespec *start, const struct timespec *end)
{
return 1e3*(end->tv_sec - start->tv_sec) + 1e-6*(end->tv_nsec - start->tv_nsec);
@@ -103,7 +112,7 @@ static uint32_t __gem_context_create(int fd)
return arg.ctx_id;
}
-static double replay(const char *filename, long nop)
+static double replay(const char *filename, long nop, long range)
{
struct timespec t_start, t_end;
struct drm_i915_gem_execbuffer2 eb = {};
@@ -158,8 +167,11 @@ static double replay(const char *filename, long nop)
fd = drm_open_driver(DRIVER_INTEL);
if (nop > 0) {
- bo[0] = gem_create(fd, nop);
- gem_write(fd, bo[0], nop - sizeof(bbe), &bbe, sizeof(bbe));
+ bo[0] = gem_create(fd, nop + range);
+ gem_write(fd, bo[0], nop + range - sizeof(bbe),
+ &bbe, sizeof(bbe));
+ range *= 2;
+ range -= 64;
} else {
bo[0] = gem_create(fd, 4096);
gem_write(fd, bo[0], 0, &bbe, sizeof(bbe));
@@ -263,6 +275,12 @@ static double replay(const char *filename, long nop)
memset(&exec_objects[eb.buffer_count++], 0,
sizeof(*exec_objects)))->handle = bo[0];
+ if (nop > 0) {
+ eb.batch_start_offset = hars_petruska_f54_1_random();
+ eb.batch_start_offset =
+ ((uint64_t)eb.batch_start_offset * range) >> 32;
+ eb.batch_start_offset = ALIGN(eb.batch_start_offset, 64);
+ }
gem_execbuf(fd, &eb);
break;
}
@@ -320,17 +338,43 @@ static long calibrate_nop(int usecs)
return size;
}
+static int measure_nop(long nop)
+{
+ const uint32_t bbe = 0xa << 23;
+ int fd = drm_open_driver(DRIVER_INTEL);
+ struct drm_i915_gem_exec_object2 obj = {};
+ struct drm_i915_gem_execbuffer2 eb = { .buffer_count = 1, .buffers_ptr = (uintptr_t)&obj};
+ struct timespec t_start, t_end;
+
+ obj.handle = gem_create(fd, nop);
+ gem_write(fd, obj.handle, nop - sizeof(bbe), &bbe, sizeof(bbe));
+ gem_execbuf(fd, &eb);
+ gem_sync(fd, obj.handle);
+
+ clock_gettime(CLOCK_MONOTONIC, &t_start);
+ for (int loop = 0; loop < 9; loop++)
+ gem_execbuf(fd, &eb);
+ gem_sync(fd, obj.handle);
+ clock_gettime(CLOCK_MONOTONIC, &t_end);
+
+ gem_close(fd, obj.handle);
+
+ close(fd);
+ return 1e3*elapsed(&t_start, &t_end) / 9;
+}
+
int main(int argc, char **argv)
{
int delay = 1000;
double *results;
long nop = 0;
+ long range = 0;
int i, c;
results = mmap(NULL, ALIGN(argc*sizeof(double), 4096),
PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
- while ((c = getopt(argc, argv, "d:n:")) != -1) {
+ while ((c = getopt(argc, argv, "d:n:r:")) != -1) {
switch (c) {
case 'd':
delay = atoi(optarg);
@@ -340,17 +384,29 @@ int main(int argc, char **argv)
if (nop > 0)
nop = ALIGN(nop, 4096);
break;
+ case 'r':
+ range = strtol(optarg, NULL, 0);
+ if (range > 0)
+ range = ALIGN(range, 4096);
+ break;
default:
break;
}
}
+
if (!nop)
nop = calibrate_nop(delay);
- if (nop > 0)
- printf("Using %lu nop batch for %dus delay\n", nop, delay);
+ if (!range)
+ range = nop / 2;
+ if (nop > 0) {
+ delay = measure_nop(nop);
+ printf("Using %lu nop batch for ~%dus delay, range %lu [%dus]\n",
+ nop, delay,
+ range, (int)(delay * range / nop));
+ }
igt_fork(child, argc-optind)
- results[child] = replay(argv[child + optind], nop);
+ results[child] = replay(argv[child + optind], nop, range);
igt_waitchildren();
for (i = 0; i < argc - optind; i++) {