add redblack tree memory overhead benchmark

This commit is contained in:
Sears Russell 2010-11-24 20:35:02 +00:00
parent 1708a716e1
commit 2ee81c62c4
4 changed files with 148 additions and 0 deletions

View file

@ -34,6 +34,7 @@ CREATE_EXECUTABLE(qos)
CREATE_EXECUTABLE(writeBack) CREATE_EXECUTABLE(writeBack)
CREATE_EXECUTABLE(distributedLsnFree) CREATE_EXECUTABLE(distributedLsnFree)
CREATE_EXECUTABLE(bufferManager) CREATE_EXECUTABLE(bufferManager)
CREATE_EXECUTABLE(redBlackMemoryOverhead)
IF(CHECK_LIBRARY) IF(CHECK_LIBRARY)
ADD_TEST(rose rose) ADD_TEST(rose rose)

View file

@ -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

View file

@ -0,0 +1,121 @@
/*
* redBlackMemoryOverhead.c
*
* Created on: Nov 17, 2010
* Author: sears
*/
#include <config.h>
#include <stasis/common.h>
#include <stasis/redblack.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
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;
}

View file

@ -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");
}