diff options
author | Tvrtko Ursulin <tvrtko.ursulin@intel.com> | 2015-06-01 11:11:15 +0100 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2015-06-02 13:51:41 +0100 |
commit | 85ee6e7b366713aca9d98d587f03eb7583f38830 (patch) | |
tree | cb80c03b856ecf859d1dad092d517e3789f447ed /benchmarks/gem_userptr_benchmark.c | |
parent | 977730084647d32b98019924b81b281bef942689 (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.c | 97 |
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(); |