From b53d2291e895c97ea537966832e116d3d36b10f8 Mon Sep 17 00:00:00 2001 From: Philippe Waroquiers Date: Thu, 29 Sep 2016 20:04:43 +0000 Subject: [PATCH] Add an optional 2nd arg to leak-autofreepool to test performance e.g. using the beloz for f in 1 2 3 4 5 6 7 8 9; do echo $f; time ./vg-in-place -q ./memcheck/tests/leak-autofreepool 2 $(expr $f \* 100000); done This shows that freeing a mempool with significant nr of elements has a bad effect on performance Note that no effort has been spent to avoid leaks in this optional perf test. This is just to analyse the time taken to free the pool. The above loop shows that a medium size pool (e.g. < 1000000 elts) can already take significant time, probably due to the quadratic algorithm to clear the pool. Note that the increase can vary a lot, probably depending on the way the blocks are spread in the hash table: when lucky, the quadratic algorithm probably somewhat becomes more linear if the elements are 'properly' ordered in the hash table by deletion order. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@15986 --- memcheck/tests/leak-autofreepool.c | 61 +++++++++++++++++++++++++++++- 1 file changed, 59 insertions(+), 2 deletions(-) diff --git a/memcheck/tests/leak-autofreepool.c b/memcheck/tests/leak-autofreepool.c index 2bee601819..44da9ebe5c 100644 --- a/memcheck/tests/leak-autofreepool.c +++ b/memcheck/tests/leak-autofreepool.c @@ -1,4 +1,4 @@ - +#include #include #include #include @@ -182,7 +182,7 @@ int main( int argc, char** argv ) int arg; size_t i; - assert(argc == 2); + assert(argc == 2 || argc == 3); assert(argv[1]); assert(strlen(argv[1]) == 1); assert(argv[1][0] >= '0' && argv[1][0] <= '9'); @@ -222,5 +222,62 @@ int main( int argc, char** argv ) // Cleanup. VALGRIND_DESTROY_MEMPOOL(PlainPool); + // Perf test + if (argc == 3) { + struct pool perf_plain_pool; + void *perf_plain_block; + struct pool perf_meta_pool; + void *perf_meta_block; + size_t pool_block_size; + int n; + int nr_elts = atoi( argv[2] ); + time_t dnow; +#define tprintf(...) (dnow = time(NULL), \ + printf(__VA_ARGS__), \ + printf(" %s", ctime(&dnow))) + + pool_block_size = nr_elts * sizeof(struct cell) + sizeof(uint8_t) + 1; + + // Create perf meta pool + VALGRIND_CREATE_META_MEMPOOL + (&perf_meta_pool, 0, 0, + VALGRIND_MEMPOOL_AUTO_FREE | VALGRIND_MEMPOOL_METAPOOL); + perf_meta_block = malloc(pool_block_size); + + VALGRIND_MEMPOOL_ALLOC(&perf_meta_pool, perf_meta_block, + pool_block_size); + + perf_meta_pool.buf = (uint8_t *) perf_meta_block; + perf_meta_pool.allocated = pool_block_size; + perf_meta_pool.used = 0; + + + perf_meta_pool.buf += sizeof(uint8_t); + perf_meta_pool.used += sizeof(uint8_t); + + // Create perf plain pool + VALGRIND_CREATE_MEMPOOL(&perf_plain_pool, 0, 0); + perf_plain_block = malloc(pool_block_size); + + perf_plain_pool.buf = (uint8_t *) perf_plain_block; + perf_plain_pool.allocated = pool_block_size;; + perf_plain_pool.used = 0; + + perf_plain_pool.buf += sizeof(uint8_t); + perf_plain_pool.used += sizeof(uint8_t); + + tprintf("allocating %d elts", nr_elts); + for (n = 0; n < nr_elts; n++) { + (void) allocate_meta_style (&perf_meta_pool, sizeof(struct cell)); + (void) allocate_plain_style (&perf_plain_pool, sizeof(struct cell)); + } + + tprintf("freeing mempool"); + VALGRIND_MEMPOOL_FREE(&perf_meta_pool, perf_meta_block); + tprintf("destroying mempool"); + VALGRIND_DESTROY_MEMPOOL(&perf_meta_pool); + tprintf("done"); + + } return 0; } -- 2.47.2