From d985053d103533685b05c6329f720b3af9421241 Mon Sep 17 00:00:00 2001 From: William Brown Date: Jan 24 2017 07:01:54 +0000 Subject: Fix partests --- diff --git a/src/sds/bpt/search.c b/src/sds/bpt/search.c index 56db098..29880dc 100644 --- a/src/sds/bpt/search.c +++ b/src/sds/bpt/search.c @@ -34,10 +34,6 @@ sds_bptree_search_node(struct sds_bptree_instance *binst, struct sds_bptree_node branch_loop: while (target_node->level > 0) { - if (target_node->item_count == 0 || target_node->item_count >= SDS_BPTREE_BRANCH) { - // Well fuck son. - printf("You're in trouble!!!"); - } while (i < target_node->item_count) { if (binst->key_cmp_fn(key, (target_node)->keys[i]) < 0) { target_node = (struct sds_bptree_node *)target_node->values[i]; diff --git a/test/benchmark.h b/test/benchmark.h index 7692b50..bc34fec 100644 --- a/test/benchmark.h +++ b/test/benchmark.h @@ -7,6 +7,7 @@ * END COPYRIGHT BLOCK **/ #include +#include struct b_tree_cb { char *name; @@ -36,6 +37,10 @@ struct thread_info { int iter; size_t tid; struct b_tree_cow_cb *ds; + size_t batchsize; + void (*op)(struct thread_info *info); + time_t sec; + long nsec; }; diff --git a/test/benchmark_par.c b/test/benchmark_par.c index bbf3f59..1ed3459 100644 --- a/test/benchmark_par.c +++ b/test/benchmark_par.c @@ -11,34 +11,34 @@ #include #include -static PRLock *the_lock; +static pthread_rwlock_t the_lock; /* The sds b+ tree wrappers */ int64_t bptree_init_wrapper(void **inst) { - the_lock = PR_NewLock(); + pthread_rwlock_init(&the_lock, NULL); struct sds_bptree_instance **binst = (struct sds_bptree_instance **)inst; sds_bptree_init(binst, 0, sds_uint64_t_compare, sds_free, sds_uint64_t_free, sds_uint64_t_dup); return 0; } int64_t bptree_read_begin(void **inst, void **txn) { - PR_Lock(the_lock); + pthread_rwlock_rdlock(&the_lock); return 0; } int64_t bptree_read_complete(void **inst, void *txn) { - PR_Unlock(the_lock); + pthread_rwlock_unlock(&the_lock); return 0; } int64_t bptree_write_begin(void **inst, void **txn) { - PR_Lock(the_lock); + pthread_rwlock_wrlock(&the_lock); return 0; } int64_t bptree_write_commit(void **inst, void *txn) { - PR_Unlock(the_lock); + pthread_rwlock_unlock(&the_lock); return 0; } @@ -74,7 +74,7 @@ int64_t bptree_destroy_wrapper(void **inst) { struct sds_bptree_instance **binst = (struct sds_bptree_instance **)inst; // sds_bptree_display(*binst); sds_bptree_destroy(*binst); - PR_DestroyLock(the_lock); + pthread_rwlock_destroy(&the_lock); return 0; } @@ -148,9 +148,8 @@ int64_t bptree_cow_destroy_wrapper(void **inst) { /* == Random and contended == */ void -bench_thread_mixed(void *arg) { - struct thread_info *info = (struct thread_info *)arg; - printf("tid %d\n", info->tid); +batch_random(struct thread_info *info) { + // printf("tid %d\n", info->tid); void *read_txn = NULL; void *write_txn = NULL; @@ -189,109 +188,32 @@ bench_thread_mixed(void *arg) { } - printf("tid %d complete\n", info->tid); + // printf("tid %d complete\n", info->tid); } void -bench_insert_search_delete_random(struct b_tree_cow_cb *ds, int iter) { - PRThread *t[10] = {0}; - struct thread_info info[10] = {0}; - void *write_txn; - - int max_factors = iter / 2048; - struct timespec start_time; - struct timespec finish_time; - - ds->init(&(ds->inst)); - - // Inject a number of elements first, just so that search and delete have - // something to work with. we won't bench this. - ds->write_begin(&(ds->inst), &write_txn); - for (size_t j = 0; j < max_factors; j++) { - for (size_t i = 0; i < 2048 ; i++) { - ds->add(&(ds->inst), write_txn, (void *)(fill_pattern[i] + (2048 << j)), NULL); - } - } - ds->write_commit(&(ds->inst), write_txn); - - - printf("BENCH: Start ...\n"); - clock_gettime(CLOCK_MONOTONIC, &start_time); - - // This launches a number of threads, and waits for them to join. - // Need some kind of thread struct to pass to it? - for (size_t i = 0; i < 10; i++) { - info[i].iter = iter; - info[i].tid = i; - info[i].ds = ds; - t[i] = PR_CreateThread(PR_USER_THREAD, bench_thread_mixed, (void *)&(info[i]), - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); - assert_ptr_not_equal(t[i], NULL); - } - - for (size_t i = 0; i < 10; i++) { - assert_int_equal(PR_JoinThread(t[i]), PR_SUCCESS); - } - - // stop time - clock_gettime(CLOCK_MONOTONIC, &finish_time); - - printf("BENCH: Complete ... \n"); - - // diff time - time_t sec = finish_time.tv_sec - start_time.tv_sec; - long nsec = finish_time.tv_nsec - start_time.tv_nsec; - - if (nsec < 0) { - // It's negative so take one second - sec -= 1; - // And set nsec to to a whole value - nsec = 1000000000 - nsec; - } - - printf("BENCH: %s bench_insert_search_delete_random %d time %" PRId64 ".%010" PRId64 "\n", ds->name, iter, sec, nsec ); - - ds->destroy(&(ds->inst)); -} - -/* == End Random and contended == */ -/* == Search thread vs write thread == */ - - -void -bench_thread_search_batch(void *arg) { - struct thread_info *info = (struct thread_info *)arg; - printf("tid %d\n", info->tid); - +batch_search(struct thread_info *info) { void *read_txn = NULL; - size_t cf = 0; size_t step = 0; - size_t current_step = 0; int max_factors = info->iter / 2048; void *output; - /* Now start stepping, and randomly deleting */ - for (step = 0; step < (info->iter * 50); step++) { + for (step = 0; step < (info->iter * 100); step++) { info->ds->read_begin(&(info->ds->inst), &read_txn); - for (size_t j = 0; j < 10; j++) { - current_step = step + j + fill_pattern[step % 2048]; - cf = step % max_factors; - void *target = (void *)(fill_pattern[step % 2048] + (2048 << cf)); + for (size_t j = 0; j < info->batchsize; j++) { + cf = (step * info->tid) % 2048; + void *target = (void *)(fill_pattern[cf] + j); info->ds->search(&(info->ds->inst), read_txn, target, &output); } info->ds->read_complete(&(info->ds->inst), read_txn); } - - printf("tid %d complete\n", info->tid); } -void -bench_thread_insert_batch(void *arg) { - struct thread_info *info = (struct thread_info *)arg; - printf("tid %d\n", info->tid); +void +batch_insert(struct thread_info *info) { void *write_txn = NULL; size_t cf = 0; @@ -303,8 +225,6 @@ bench_thread_insert_batch(void *arg) { for (size_t i = 0; i < info->tid; i++) { baseid += 50000; } - - /* Now start stepping, and randomly deleting */ for (step = 0; step < (info->iter * 50); step++) { info->ds->write_begin(&(info->ds->inst), &write_txn); for (size_t j = 0; j < 10; j++) { @@ -316,15 +236,10 @@ bench_thread_insert_batch(void *arg) { } info->ds->write_commit(&(info->ds->inst), write_txn); } - - printf("tid %d complete\n", info->tid); } void -bench_thread_delete_batch(void *arg) { - struct thread_info *info = (struct thread_info *)arg; - printf("tid %d\n", info->tid); - +batch_delete(struct thread_info *info) { void *write_txn = NULL; size_t cf = 0; @@ -336,7 +251,6 @@ bench_thread_delete_batch(void *arg) { for (size_t i = 0; i < info->tid; i++) { baseid += 50000; } - /* Now start stepping, and randomly deleting */ for (step = 0; step < (info->iter * 50); step++) { info->ds->write_begin(&(info->ds->inst), &write_txn); @@ -349,19 +263,71 @@ bench_thread_delete_batch(void *arg) { } info->ds->write_commit(&(info->ds->inst), write_txn); } +} + +void +bench_thread_batch(void *arg) { + struct thread_info *info = (struct thread_info *)arg; + // printf("tid %d\n", info->tid); + struct timespec start_time; + struct timespec finish_time; + + clock_gettime(CLOCK_MONOTONIC, &start_time); + + info->op(info); + + // stop time + clock_gettime(CLOCK_MONOTONIC, &finish_time); + // printf("tid %d complete\n", info->tid); + info->sec = finish_time.tv_sec - start_time.tv_sec; + info->nsec = finish_time.tv_nsec - start_time.tv_nsec; + + if (info->nsec < 0) { + // It's negative so take one second + info->sec -= 1; + // And set nsec to to a whole value + info->nsec = 1000000000 - info->nsec; + } +} + +void +batch_test_run(struct b_tree_cow_cb *ds, int iter, char *name, struct thread_info *info, size_t info_count) { + PRThread *t[10] = {0}; - printf("tid %d complete\n", info->tid); + + printf("BENCH: Start ...\n"); + + // This launches a number of threads, and waits for them to join. + // Need some kind of thread struct to pass to it? + + for (size_t i = 0; i < info_count; i++) { + t[i] = PR_CreateThread(PR_USER_THREAD, bench_thread_batch, (void *)&(info[i]), + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); + assert_ptr_not_equal(t[i], NULL); + } + + for (size_t i = 0; i < info_count; i++) { + assert_int_equal(PR_JoinThread(t[i]), PR_SUCCESS); + } + + printf("BENCH: Complete ... \n"); + + printf("BENCH: %s %s %d times\n", ds->name, name, iter); + for (size_t i = 0; i < info_count; i++) { + printf(" tid %d: %" PRId64 ".%010" PRId64 "\n", info[i].tid, info[i].sec, info[i].nsec); + } } +/* Batch running */ + +/* Now we can just construct some generic tests. */ + void bench_insert_search_delete_batch(struct b_tree_cow_cb *ds, int iter) { - PRThread *t[10] = {0}; struct thread_info info[10] = {0}; void *write_txn; - int max_factors = iter / 2048; - struct timespec start_time; - struct timespec finish_time; + size_t max_factors = iter / 2048; ds->init(&(ds->inst)); @@ -370,69 +336,70 @@ bench_insert_search_delete_batch(struct b_tree_cow_cb *ds, int iter) { ds->write_begin(&(ds->inst), &write_txn); for (size_t j = 0; j < max_factors; j++) { for (size_t i = 0; i < 2048 ; i++) { - ds->add(&(ds->inst), write_txn, (void *)(fill_pattern[i] + (2048 << j)), NULL); + ds->add(&(ds->inst), write_txn, (void *)(fill_pattern[i] + (2048 * j)), NULL); } } ds->write_commit(&(ds->inst), write_txn); - - - printf("BENCH: Start ...\n"); - clock_gettime(CLOCK_MONOTONIC, &start_time); - - // This launches a number of threads, and waits for them to join. - // Need some kind of thread struct to pass to it? - size_t i = 0; + size_t i = 0; for (; i < 2; i++) { info[i].iter = iter; info[i].tid = i; info[i].ds = ds; - t[i] = PR_CreateThread(PR_USER_THREAD, bench_thread_insert_batch, (void *)&(info[i]), - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); - assert_ptr_not_equal(t[i], NULL); + info[i].op = batch_insert; + info[i].batchsize = 10; } for (; i < 3; i++) { info[i].iter = iter; info[i].tid = i; info[i].ds = ds; - t[i] = PR_CreateThread(PR_USER_THREAD, bench_thread_delete_batch, (void *)&(info[i]), - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); - assert_ptr_not_equal(t[i], NULL); + info[i].op = batch_delete; + info[i].batchsize = 10; } for (; i < 10; i++) { info[i].iter = iter; info[i].tid = i; info[i].ds = ds; - t[i] = PR_CreateThread(PR_USER_THREAD, bench_thread_search_batch, (void *)&(info[i]), - PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); - assert_ptr_not_equal(t[i], NULL); + info[i].op = batch_search; + info[i].batchsize = 10; } - for (size_t i = 0; i < 10; i++) { - assert_int_equal(PR_JoinThread(t[i]), PR_SUCCESS); - } + batch_test_run(ds, iter, "bench_insert_search_delete_batch", info, 10); - // stop time - clock_gettime(CLOCK_MONOTONIC, &finish_time); + ds->destroy(&(ds->inst)); +} - printf("BENCH: Complete ... \n"); +void +bench_insert_search_delete_random(struct b_tree_cow_cb *ds, int iter) { + struct thread_info info[10] = {0}; + void *write_txn; - // diff time - time_t sec = finish_time.tv_sec - start_time.tv_sec; - long nsec = finish_time.tv_nsec - start_time.tv_nsec; + size_t max_factors = iter / 2048; - if (nsec < 0) { - // It's negative so take one second - sec -= 1; - // And set nsec to to a whole value - nsec = 1000000000 - nsec; - } + ds->init(&(ds->inst)); - printf("BENCH: %s bench_insert_search_delete_random %d time %" PRId64 ".%010" PRId64 "\n", ds->name, iter, sec, nsec ); + // Inject a number of elements first, just so that search and delete have + // something to work with. we won't bench this. + ds->write_begin(&(ds->inst), &write_txn); + for (size_t j = 0; j < max_factors; j++) { + for (size_t i = 0; i < 2048 ; i++) { + ds->add(&(ds->inst), write_txn, (void *)(fill_pattern[i] + (2048 * j)), NULL); + } + } + ds->write_commit(&(ds->inst), write_txn); + size_t i = 0; + for (; i < 10; i++) { + info[i].iter = iter; + info[i].tid = i; + info[i].ds = ds; + info[i].op = batch_random; + info[i].batchsize = 10; + } + batch_test_run(ds, iter, "bench_insert_search_delete_random", info, 10); ds->destroy(&(ds->inst)); } -/* == end Search thread vs write thread == */ +/* End tests */ int main (int argc __attribute__((unused)), char **argv __attribute__((unused))) {