[PATCH i-g-t 06/13] i915/gem_create: Measure object creation latency for different memory regions

Zbigniew Kempczyński zbigniew.kempczynski at intel.com
Mon Aug 29 13:50:38 UTC 2022


From: Chris Wilson <chris.p.wilson at intel.com>

Ideally all objects are equally fast, with discrete faster than all.

Signed-off-by: Chris Wilson <chris.p.wilson at intel.com>
---
 tests/i915/gem_create.c | 138 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 138 insertions(+)

diff --git a/tests/i915/gem_create.c b/tests/i915/gem_create.c
index 13fba35bae..8e498b7e75 100644
--- a/tests/i915/gem_create.c
+++ b/tests/i915/gem_create.c
@@ -338,6 +338,99 @@ static void busy_create(int i915, const struct gem_memory_region *r, int timeout
 	gem_quiescent_gpu(i915);
 }
 
+static const char *size_repr(uint64_t sz, char *buf, size_t len)
+{
+	const char *unit;
+
+	if (sz < 1ull << 20) {
+		unit = "KiB";
+		sz >>= 10;
+	} else if (sz < 1ull << 30) {
+		unit = "MiB";
+		sz >>= 20;
+	} else {
+		unit = "GiB";
+		sz >>= 30;
+	}
+
+	snprintf(buf, len, "%"PRIu64"%s", sz, unit);
+	return buf;
+}
+
+static struct region_limits {
+	uint64_t min, max;
+} max_create_limits(int i915)
+{
+	struct region_limits l = { 0, -1 };
+
+	for_each_memory_region(r, i915) {
+		uint32_t handle;
+		uint64_t sz;
+
+		sz = 4096;
+		igt_assert_eq(__gem_create_in_memory_region_list(i915, &handle, &sz, 0, &r->ci, 1), 0);
+		gem_close(i915, handle);
+
+		if (sz > l.min)
+			l.min = sz;
+
+		if (r->size < l.max)
+			l.max = r->size;
+	}
+
+	return l;
+}
+
+static void
+max_create(int i915, const struct gem_memory_region *r, const struct region_limits *l, unsigned int flags)
+#define MAX_POPULATE 0x1
+#define MAX_RESIDENT 0x2
+#define MAX_OVERLAP 0x4
+{
+	int probe = !(flags & MAX_OVERLAP);
+
+	for (uint64_t size = l->min; size <= l->max / 2; size *= 2) {
+		for (uint64_t total = size; total <= l->max / 2; total *= 2) {
+			unsigned long count = total / size;
+			int fd = gem_reopen_driver(i915);
+			uint32_t batch = batch_create(fd);
+			uint32_t handle[2];
+			struct timespec tv;
+			uint64_t elapsed;
+			char str[80];
+
+			igt_nsec_elapsed(memset(&tv, 0, sizeof(tv)));
+			handle[0] = gem_create_in_memory_region_list(fd, size, 0, &r->ci, 1);
+			while (count--) {
+				handle[1] = gem_create_in_memory_region_list(fd, size, 0, &r->ci, 1);
+				if (flags & MAX_POPULATE) {
+					char *ptr = gem_mmap__device_coherent(fd, handle[probe], 0, size, PROT_READ);
+					gem_set_domain(fd, handle[probe], I915_GEM_DOMAIN_WC, 0);
+					for (int p = 0; p < size; p += 4096)
+						igt_assert_eq(ptr[p], 0);
+					munmap(ptr, size);
+				}
+
+				if (flags & MAX_RESIDENT)
+					make_resident(fd, batch, handle[probe]);
+
+				handle[0] = handle[1];
+			}
+			if (flags & MAX_RESIDENT)
+				gem_sync(fd, batch);
+			elapsed = igt_nsec_elapsed(&tv);
+			close(fd); /* discard all the objects at once */
+
+			igt_info("%s: %s %9lu %s objects took %.1fms\n",
+					r->name,
+					flags & MAX_POPULATE ? "Populating" : "Creating",
+					total / size,
+					size_repr(size, str, sizeof(str)),
+					elapsed * 1e-6);
+		}
+	}
+}
+
 static void size_update(int fd)
 {
 	int size_initial_nonaligned = 15;
@@ -884,6 +977,51 @@ igt_main
 			igt_stop_hang_detector();
 	}
 
+	igt_subtest_with_dynamic("max-create") {
+		struct region_limits limits = max_create_limits(fd);
+
+		for_each_memory_region(r, fd) {
+			igt_dynamic_f("%s", r->name)
+				max_create(fd, r, &limits, 0);
+		}
+	}
+
+	igt_subtest_with_dynamic("max-populate0") {
+		struct region_limits limits = max_create_limits(fd);
+
+		for_each_memory_region(r, fd) {
+			igt_dynamic_f("%s", r->name)
+				max_create(fd, r, &limits, MAX_POPULATE);
+		}
+	}
+
+	igt_subtest_with_dynamic("max-populate1") {
+		struct region_limits limits = max_create_limits(fd);
+
+		for_each_memory_region(r, fd) {
+			igt_dynamic_f("%s", r->name)
+				max_create(fd, r, &limits, MAX_POPULATE | MAX_OVERLAP);
+		}
+	}
+
+	igt_subtest_with_dynamic("max-resident0") {
+		struct region_limits limits = max_create_limits(fd);
+
+		for_each_memory_region(r, fd) {
+			igt_dynamic_f("%s", r->name)
+				max_create(fd, r, &limits, MAX_RESIDENT);
+		}
+	}
+
+	igt_subtest_with_dynamic("max-resident1") {
+		struct region_limits limits = max_create_limits(fd);
+
+		for_each_memory_region(r, fd) {
+			igt_dynamic_f("%s", r->name)
+				max_create(fd, r, &limits, MAX_RESIDENT | MAX_OVERLAP);
+		}
+	}
+
 	igt_describe("Exercise create_ext placements extension.");
 	igt_subtest("create-ext-placement-sanity-check")
 		create_ext_placement_sanity_check(fd);
-- 
2.34.1



More information about the Intel-gfx-trybot mailing list