summaryrefslogtreecommitdiff
path: root/benchmarks/gem_userptr_benchmark.c
diff options
context:
space:
mode:
authorTvrtko Ursulin <tvrtko.ursulin@intel.com>2015-06-01 11:11:15 +0100
committerChris Wilson <chris@chris-wilson.co.uk>2015-06-02 13:51:41 +0100
commit85ee6e7b366713aca9d98d587f03eb7583f38830 (patch)
treecb80c03b856ecf859d1dad092d517e3789f447ed /benchmarks/gem_userptr_benchmark.c
parent977730084647d32b98019924b81b281bef942689 (diff)
gem_userptr_benchmark: Test overlapping bo mmu notifier performance impact
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@intel.com> Cc: Chris Wilson <chris@chris-wilson.co.uk> Cc: Thomas Daniel <thomas.daniel@intel.com>
Diffstat (limited to 'benchmarks/gem_userptr_benchmark.c')
-rw-r--r--benchmarks/gem_userptr_benchmark.c97
1 files changed, 74 insertions, 23 deletions
diff --git a/benchmarks/gem_userptr_benchmark.c b/benchmarks/gem_userptr_benchmark.c
index 4d7442bf..b804fdd5 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();