[Intel-gfx] [PATCH i-g-t] gem_userptr_benchmark: Test overlapping bo mmu notifier performance impact
Tvrtko Ursulin
tvrtko.ursulin at linux.intel.com
Mon Jun 1 03:11:15 PDT 2015
From: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
Current userptr kernel implementation downgrades tracking VMA ranges (real
userspace ones) to an inefficient linear walk for any process which has
instantiated overlapping userptr objects.
This adds a test which shows the performance cliff on, most visibly, generic
userspace mmap(2) and munmap(2) operations between unsync, non-overlapping
and overlapping userptr objects.
Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
Cc: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Thomas Daniel <thomas.daniel at intel.com>
---
benchmarks/gem_userptr_benchmark.c | 97 +++++++++++++++++++++++++++++---------
1 file changed, 74 insertions(+), 23 deletions(-)
diff --git a/benchmarks/gem_userptr_benchmark.c b/benchmarks/gem_userptr_benchmark.c
index 4d7442b..b804fdd 100644
--- a/benchmarks/gem_userptr_benchmark.c
+++ b/benchmarks/gem_userptr_benchmark.c
@@ -180,7 +180,7 @@ static int has_userptr(int fd)
return handle != 0;
}
-static const unsigned int nr_bos[] = {0, 1, 10, 100, 1000};
+static const unsigned int nr_bos[] = {0, 1, 10, 100, 1000, 10000};
static const unsigned int test_duration_sec = 3;
static volatile unsigned int run_test;
@@ -334,43 +334,88 @@ static void test_ptr_write(void *ptr)
printf("%8lu MB/s\n", iter / test_duration_sec * BO_SIZE / 1000000);
}
-static void test_impact(int fd)
+static void do_impact_tests(unsigned int n, const char *pfix, const char *pfix2,
+ void *ptr)
+{
+ printf("%s%sptr-read, %5u bos = ", pfix, pfix2, n);
+ test_ptr_read(ptr);
+
+ printf("%s%sptr-write %5u bos = ", pfix, pfix2, n);
+ test_ptr_write(ptr);
+
+ printf("%s%smalloc-free, %5u bos = ", pfix, pfix2, n);
+ test_malloc_free(0);
+ printf("%s%smalloc-free-random %5u bos = ", pfix, pfix2, n);
+ test_malloc_free(1);
+
+ printf("%s%smalloc-realloc-free, %5u bos = ", pfix, pfix2, n);
+ test_malloc_realloc_free(0);
+ printf("%s%smalloc-realloc-free-random, %5u bos = ", pfix, pfix2, n);
+ test_malloc_realloc_free(1);
+
+ printf("%s%smmap-unmap, %5u bos = ", pfix, pfix2, n);
+ test_mmap_unmap(0);
+ printf("%s%smmap-unmap-random, %5u bos = ", pfix, pfix2, n);
+ test_mmap_unmap(1);
+}
+
+static void test_impact_overlap(int fd, const char *prefix)
{
unsigned int total = sizeof(nr_bos) / sizeof(nr_bos[0]);
unsigned int subtest, i;
uint32_t handles[nr_bos[total-1]];
+ void *block = NULL;
void *ptr;
+ unsigned char *p;
char buffer[BO_SIZE];
+ int ret;
for (subtest = 0; subtest < total; subtest++) {
- for (i = 0; i < nr_bos[subtest]; i++)
- handles[i] = create_userptr_bo(fd, BO_SIZE);
+ if (nr_bos[subtest] > 0) {
+ igt_assert(PAGE_SIZE < BO_SIZE);
+ ret = posix_memalign(&block, PAGE_SIZE,
+ PAGE_SIZE * nr_bos[subtest] + BO_SIZE);
+ igt_assert(ret == 0);
+
+ for (i = 0, p = block; i < nr_bos[subtest];
+ i++, p += PAGE_SIZE)
+ ret = gem_userptr(fd, (uint32_t *)p, BO_SIZE, 0,
+ &handles[i]);
+ igt_assert(ret == 0);
+ }
if (nr_bos[subtest] > 0)
- ptr = get_handle_ptr(handles[0]);
+ ptr = block;
else
ptr = buffer;
- printf("ptr-read, %5u bos = ", nr_bos[subtest]);
- test_ptr_read(ptr);
+ do_impact_tests(nr_bos[subtest], prefix, "overlap-", ptr);
- printf("ptr-write %5u bos = ", nr_bos[subtest]);
- test_ptr_write(ptr);
+ for (i = 0; i < nr_bos[subtest]; i++)
+ gem_close(fd, handles[i]);
+ if (block)
+ free(block);
+ }
+}
- printf("malloc-free, %5u bos = ", nr_bos[subtest]);
- test_malloc_free(0);
- printf("malloc-free-random %5u bos = ", nr_bos[subtest]);
- test_malloc_free(1);
+static void test_impact(int fd, const char *prefix)
+{
+ unsigned int total = sizeof(nr_bos) / sizeof(nr_bos[0]);
+ unsigned int subtest, i;
+ uint32_t handles[nr_bos[total-1]];
+ void *ptr;
+ char buffer[BO_SIZE];
- printf("malloc-realloc-free, %5u bos = ", nr_bos[subtest]);
- test_malloc_realloc_free(0);
- printf("malloc-realloc-free-random, %5u bos = ", nr_bos[subtest]);
- test_malloc_realloc_free(1);
+ for (subtest = 0; subtest < total; subtest++) {
+ for (i = 0; i < nr_bos[subtest]; i++)
+ handles[i] = create_userptr_bo(fd, BO_SIZE);
- printf("mmap-unmap, %5u bos = ", nr_bos[subtest]);
- test_mmap_unmap(0);
- printf("mmap-unmap-random, %5u bos = ", nr_bos[subtest]);
- test_mmap_unmap(1);
+ if (nr_bos[subtest] > 0)
+ ptr = get_handle_ptr(handles[0]);
+ else
+ ptr = buffer;
+
+ do_impact_tests(nr_bos[subtest], prefix, "no-overlap-", ptr);
for (i = 0; i < nr_bos[subtest]; i++)
free_userptr_bo(fd, handles[i]);
@@ -484,7 +529,10 @@ int main(int argc, char **argv)
test_userptr(fd);
igt_subtest("userptr-impact-unsync")
- test_impact(fd);
+ test_impact(fd, "unsync-");
+
+ igt_subtest("userptr-impact-unsync-overlap")
+ test_impact_overlap(fd, "unsync-");
gem_userptr_test_synchronized();
@@ -492,7 +540,10 @@ int main(int argc, char **argv)
test_userptr(fd);
igt_subtest("userptr-impact-sync")
- test_impact(fd);
+ test_impact(fd, "sync-");
+
+ igt_subtest("userptr-impact-sync-overlap")
+ test_impact_overlap(fd, "sync-");
igt_exit();
--
2.4.0
More information about the Intel-gfx
mailing list