From 2ee81c62c404c1ecd0c9e3c13d4d350f0981b5e1 Mon Sep 17 00:00:00 2001 From: Sears Russell Date: Wed, 24 Nov 2010 20:35:02 +0000 Subject: [PATCH] add redblack tree memory overhead benchmark --- benchmarks/CMakeLists.txt | 1 + benchmarks/README.run_redBlackMemoryOverhead | 10 ++ benchmarks/redBlackMemoryOverhead.c | 121 +++++++++++++++++++ benchmarks/run_redBlackMemoryOverhead.pl | 16 +++ 4 files changed, 148 insertions(+) create mode 100644 benchmarks/README.run_redBlackMemoryOverhead create mode 100644 benchmarks/redBlackMemoryOverhead.c create mode 100755 benchmarks/run_redBlackMemoryOverhead.pl diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt index eabfe81..6076da9 100644 --- a/benchmarks/CMakeLists.txt +++ b/benchmarks/CMakeLists.txt @@ -34,6 +34,7 @@ CREATE_EXECUTABLE(qos) CREATE_EXECUTABLE(writeBack) CREATE_EXECUTABLE(distributedLsnFree) CREATE_EXECUTABLE(bufferManager) +CREATE_EXECUTABLE(redBlackMemoryOverhead) IF(CHECK_LIBRARY) ADD_TEST(rose rose) diff --git a/benchmarks/README.run_redBlackMemoryOverhead b/benchmarks/README.run_redBlackMemoryOverhead new file mode 100644 index 0000000..416d0f6 --- /dev/null +++ b/benchmarks/README.run_redBlackMemoryOverhead @@ -0,0 +1,10 @@ +README for red black tree memory benchmark +------------------------------------------ + +To run the benchmark, see redBlackMemoryOverhead.c and run_redBlackMemoryOverhead.pl. + +To post-process the output into tab-delimited file suitable for further analysis: + +grep -i results file*.out | tr -s ' ' '\t' > results.txt + + diff --git a/benchmarks/redBlackMemoryOverhead.c b/benchmarks/redBlackMemoryOverhead.c new file mode 100644 index 0000000..d9d957b --- /dev/null +++ b/benchmarks/redBlackMemoryOverhead.c @@ -0,0 +1,121 @@ +/* + * redBlackMemoryOverhead.c + * + * Created on: Nov 17, 2010 + * Author: sears + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct { + uint64_t key; + unsigned char * value; +} entry; + +int cmp(const void *ap, const void *bp, const void *ign) { + const entry *a = ap, *b = bp; + return (a->key < b->key) ? -1 : (a->key == b->key) ? 0 : 1; +} + +int main(int argc, char * argv[]) { + if(argc != 3) { + printf("Usage: %s [db size-in-mb] [tuple size in bytes]\n", argv[0]); + return 1; + } + int64_t contents_size = atoll(argv[1]) * (1024 * 1024); + int32_t tuple_size = atoi(argv[2]); + int64_t tuple_count = contents_size / tuple_size; + int64_t tree_count = 0; + printf("tuple count = %lld / %lld = %lld\n", (long long) contents_size, (long long) tuple_size, (long long)tuple_count); fflush(stdout); + + int64_t last_memory_usage = 0; + + entry dummy; + dummy.key = 0; + struct rbtree *tree = rbinit(cmp,0); + uint64_t iter = 0; + int quiesce_count = 0; + while(1) { + if(tree_count < tuple_count) { +// printf("a1000"); +// for(int i = 0; i < 1000; i++) { + entry * e = malloc(sizeof(*e)); + e->key = ((uint64_t)random()) * (uint64_t)random(); + int sz = random() % (2 * tuple_size - sizeof(e)); + e->value = malloc(sz); + for(int j = 0; j < (sz); j++) { + e->value[j] = (unsigned char) (j & 255); + } + entry * f = (entry*)/*no-const*/rbsearch(e, tree); + if(f == e) { + tree_count++; + } else { + free (e->value); + free (e); + } +// } + } else { + const entry * e = rblookup(RB_LUGTEQ, &dummy, tree); +// printf("d"); + if(!e) { + dummy.key = 0; + } else { + rbdelete(e, tree); + free(e->value); + free((void*)e); + tree_count--; + } + } + if(! (iter & ((1 << 20)-1))) { +// printf("%lld:\n", (long long)iter); + int fd = open("/proc/self/statm", O_RDONLY); + char buf[40]; + read(fd, buf, 40); + buf[39] = 0; + close(fd); + int64_t mem = (atol(buf) * 4096) / (1024 * 1024); + printf("# %lldmb\n", (long long) mem); fflush(stdout); + if(mem > 8000) { + printf("FAIL\n"); fflush(stdout); + break; + } + if(mem <= last_memory_usage) { + quiesce_count ++; + if(quiesce_count == 10) { + printf("Results: %lld %lld %lld %lld (|tuple|, #tuples, actual mem, target mem)\n", (long long) tuple_size, (long long) tuple_count, (long long) mem, (long long) contents_size); fflush(stdout); + break; + } + } else { + last_memory_usage = mem; + quiesce_count = 0; + } +// system("free -m"); + +#if 0 + break; +#endif + } + iter++; + + } + + // Tear down tree (need to do this so that valgrind can check for memory leaks...) + dummy.key = 0; + while(1) { + const entry * e = rblookup(RB_LUGTEQ, &dummy, tree); + if(!e) { break; } + rbdelete(e, tree); + free(e->value); + free((void*)e); + tree_count--; + } + rbdestroy(tree); + return 0; +} diff --git a/benchmarks/run_redBlackMemoryOverhead.pl b/benchmarks/run_redBlackMemoryOverhead.pl new file mode 100755 index 0000000..17be08a --- /dev/null +++ b/benchmarks/run_redBlackMemoryOverhead.pl @@ -0,0 +1,16 @@ +#!/usr/local/bin/perl -w +use strict; + +$| = 1; + +#for my $i (qw(100 500 1000 1500)) { # ram size (mb) +# for my $j (qw(10000 1000 100 10)) { # tuple size (b) +# system("../build/benchmarks/redBlackMemoryOverhead $i $j"); +# } +#} + +for(my $i = 0; $i < 1000; $i++) { + my $i = rand(4000); + my $j = rand(10000) + 10; + system("../build/benchmarks/redBlackMemoryOverhead $i $j"); +}