From d0eb54d0301137ce70f8f8dcf5f29dea5eee482f Mon Sep 17 00:00:00 2001 From: Davi de Castro Reis Date: Tue, 15 Feb 2011 14:49:08 -0500 Subject: [PATCH] Finishing benchmarks. --- src/Makefile.am | 9 +++- src/bdz.c | 5 +-- src/bm_numbers.c | 98 ++++++++++++++++++++++++++++++++++++++--- src/cmph_benchmark.c | 11 +++-- src/jenkins_hash.c | 2 +- src/linear_string_map.c | 68 ++++++++++++++++++++++++++++ src/linear_string_map.h | 13 ++++++ 7 files changed, 191 insertions(+), 15 deletions(-) create mode 100644 src/linear_string_map.c create mode 100644 src/linear_string_map.h diff --git a/src/Makefile.am b/src/Makefile.am index 7593321..4b6e5b4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,6 @@ bin_PROGRAMS = cmph check_PROGRAMS = cmph_benchmark_test +noinst_PROGRAMS = bm_numbers lib_LTLIBRARIES = libcmph.la include_HEADERS = cmph.h cmph_types.h cmph_time.h chd_ph.h libcmph_la_SOURCES = hash.h hash.c \ @@ -24,7 +25,8 @@ libcmph_la_SOURCES = hash.h hash.c \ select.h select.c select_lookup_tables.h \ compressed_seq.h compressed_seq.c \ compressed_rank.h compressed_rank.c \ - cmph_benchmark.h cmph_benchmark.cc \ + linear_string_map.h linear_string_map.c \ + cmph_benchmark.h cmph_benchmark.c \ cmph_time.h libcmph_la_LDFLAGS = -version-info 0:0:0 @@ -32,5 +34,8 @@ libcmph_la_LDFLAGS = -version-info 0:0:0 cmph_SOURCES = main.c wingetopt.h wingetopt.c cmph_LDADD = libcmph.la -cmph_benchmark_test_SOURCES = cmph_benchmark_test.cc +cmph_benchmark_test_SOURCES = cmph_benchmark_test.c cmph_benchmark_test_LDADD = libcmph.la + +bm_numbers_SOURCES = bm_numbers.c +bm_numbers_LDADD = libcmph.la diff --git a/src/bdz.c b/src/bdz.c index 1c49c9d..e129c51 100755 --- a/src/bdz.c +++ b/src/bdz.c @@ -178,7 +178,9 @@ static int bdz_generate_queue(cmph_uint32 nedges, cmph_uint32 nvertices, bdz_que }; }; DEBUGP("Queue head %d Queue tail %d\n", queue_head, queue_tail); + #ifdef DEBUG bdz_dump_graph(graph3,graph3->nedges,graph3->nedges+graph3->nedges/4); + #endif while(queue_tail!=queue_head){ curr_edge=queue[queue_tail++]; bdz_remove_edge(graph3,curr_edge); @@ -444,7 +446,6 @@ static void assigning(bdz_config_data_t *bdz, bdz_graph3_t* graph3, bdz_queue_t SETBIT(marked_vertices, v2); } SETVALUE1(bdz->g, v0, (6-(GETVALUE(bdz->g, v1) + GETVALUE(bdz->g,v2)))%3); - if (v0 == 291) fprintf(stderr, "Vertex 291 updated at case 1\n"); SETBIT(marked_vertices, v0); } else if(!GETBIT(marked_vertices, v1)) { if(!GETBIT(marked_vertices, v2)) @@ -453,11 +454,9 @@ static void assigning(bdz_config_data_t *bdz, bdz_graph3_t* graph3, bdz_queue_t SETBIT(marked_vertices, v2); } SETVALUE1(bdz->g, v1, (7-(GETVALUE(bdz->g, v0)+GETVALUE(bdz->g, v2)))%3); - if (v1 == 291) fprintf(stderr, "Vertex 291 updated at case 1\n"); SETBIT(marked_vertices, v1); }else { SETVALUE1(bdz->g, v2, (8-(GETVALUE(bdz->g,v0)+GETVALUE(bdz->g, v1)))%3); - if (v2 == 291) fprintf(stderr, "Vertex 291 updated at case 1\n"); SETBIT(marked_vertices, v2); } DEBUGP("A:%u %u %u -- %u %u %u\n", v0, v1, v2, GETVALUE(bdz->g, v0), GETVALUE(bdz->g, v1), GETVALUE(bdz->g, v2)); diff --git a/src/bm_numbers.c b/src/bm_numbers.c index 4fa23d9..4d464c0 100644 --- a/src/bm_numbers.c +++ b/src/bm_numbers.c @@ -1,12 +1,100 @@ +#include +#include + +#include "bitbool.h" #include "cmph.h" #include "cmph_benchmark.h" +#include "linear_string_map.h" -void bm_bdz_numbers(int iters) { - cmph_config_t config; - config.algo = CMPH_BMZ; +// Generates a vector with random unique 32 bits integers +cmph_uint32* random_numbers_vector_new(cmph_uint32 size) { + cmph_uint32 i = 0; + cmph_uint32 dup_bits = sizeof(cmph_uint32)*size*8; + char* dup = (char*)malloc(dup_bits/8); + cmph_uint32* vec = (cmph_uint32 *)malloc(sizeof(cmph_uint32)*size); + memset(dup, 0, dup_bits/8); + for (i = 0; i < size; ++i) { + cmph_uint32 v = random(); + while (GETBIT(dup, v % dup_bits)) { v = random(); } + SETBIT(dup, v % dup_bits); + vec[i] = v; + fprintf(stderr, "v[%u] = %u\n", i, vec[i]); + } + free(dup); + return vec; +} +static cmph_uint32 g_numbers_len = 0; +static cmph_uint32 *g_numbers = NULL; +static lsmap_t *g_created_mphf = NULL; + +void bm_create(CMPH_ALGO algo, int iters) { + cmph_uint32 i = 0; + cmph_io_adapter_t* source = NULL; + cmph_config_t* config = NULL; + cmph_t* mphf = NULL; + + if (iters > g_numbers_len) { + fprintf(stderr, "No input with proper size."); + exit(-1); + } + + source = cmph_io_struct_vector_adapter( + (void*)g_numbers, sizeof(cmph_uint32), + 0, sizeof(cmph_uint32), iters); + config = cmph_config_new(source); + cmph_config_set_algo(config, algo); + mphf = cmph_new(config); + if (!mphf) { + fprintf(stderr, "Failed to create mphf for algorithm %s with %u keys", + cmph_names[algo], iters); + exit(-1); + } + cmph_config_destroy(config); + cmph_io_struct_vector_adapter_destroy(source); -int main(int argc, char** argv) { - run_benchmarks(argc, argv); + char mphf_name[128]; + snprintf(mphf_name, 128, "%s:%u", cmph_names[algo], iters); + lsmap_append(g_created_mphf, strdup(mphf_name), mphf); +} + +void bm_search(CMPH_ALGO algo, int iters) { + int i = 0; + char mphf_name[128]; + cmph_t* mphf = NULL; + + snprintf(mphf_name, 128, "%s:%u", cmph_names[algo], iters); + mphf = lsmap_search(g_created_mphf, mphf_name); + for (i = 0; i < iters * 100; ++i) { + cmph_uint32 pos = random() % iters; + fprintf(stderr, "Looking for key %u at pos %u\n", g_numbers[pos], pos); + const char* buf = (const char*)(g_numbers + pos); + cmph_uint32 h = cmph_search(mphf, buf, sizeof(cmph_uint32)); + fprintf(stderr, "Found h %u value %u\n", h, g_numbers[h]); + if (h != pos) { + fprintf(stderr, "Buggy mphf\n"); + } + } +} + +#define DECLARE_ALGO(algo) \ + void bm_create_ ## algo(int iters) { bm_create(algo, iters); } \ + void bm_search_ ## algo(int iters) { bm_search(algo, iters); } + +DECLARE_ALGO(CMPH_BDZ); + +int main(int argc, char** argv) { + g_numbers_len = 20; + g_numbers = random_numbers_vector_new(g_numbers_len); + g_created_mphf = lsmap_new(); + + BM_REGISTER(bm_create_CMPH_BDZ, 20); + BM_REGISTER(bm_search_CMPH_BDZ, 20); + run_benchmarks(argc, argv); + + free(g_numbers); + lsmap_foreach_key(g_created_mphf, free); + lsmap_foreach_value(g_created_mphf, cmph_destroy); + lsmap_destroy(g_created_mphf); } diff --git a/src/cmph_benchmark.c b/src/cmph_benchmark.c index b63bb84..073f937 100644 --- a/src/cmph_benchmark.c +++ b/src/cmph_benchmark.c @@ -3,12 +3,14 @@ #include #include #include +#include #include "cmph_benchmark.h" typedef struct { const char* name; void (*func)(int); + int iters; struct rusage begin; struct rusage end; } benchmark_t; @@ -65,6 +67,7 @@ void bm_register(const char* name, void (*func)(int), int iters) { int length = global_benchmarks_length(); benchmark.name = name; benchmark.func = func; + benchmark.iters = iters; assert(!find_benchmark(name)); global_benchmarks = realloc( global_benchmarks, (length + 2)*sizeof(benchmark_t)); @@ -85,7 +88,7 @@ void bm_start(const char* name) { exit(-1); } benchmark->begin = rs; - (*benchmark->func)(1); + (*benchmark->func)(benchmark->iters); } void bm_end(const char* name) { @@ -107,9 +110,9 @@ void bm_end(const char* name) { timeval_subtract(&stime, &benchmark->end.ru_stime, &benchmark->begin.ru_stime); printf("Benchmark: %s\n", benchmark->name); - printf("User time used : %ld.%6ld\n", utime.tv_sec, utime.tv_usec); - printf("System time used: %ld.%6ld\n", stime.tv_sec, stime.tv_usec); - printf("Wall time used : %ld.%6ld\n", stime.tv_sec, stime.tv_usec); + printf("User time used : %ld.%06ld\n", utime.tv_sec, utime.tv_usec); + printf("System time used: %ld.%06ld\n", stime.tv_sec, stime.tv_usec); + printf("Wall time used : %ld.%06ld\n", stime.tv_sec, stime.tv_usec); printf("\n"); } diff --git a/src/jenkins_hash.c b/src/jenkins_hash.c index 5d4e807..8fd3836 100644 --- a/src/jenkins_hash.c +++ b/src/jenkins_hash.c @@ -7,7 +7,7 @@ #include #include -#define DEBUG +// #define DEBUG #include "debug.h" #include "MurmurHash2.h" diff --git a/src/linear_string_map.c b/src/linear_string_map.c new file mode 100644 index 0000000..4390c5b --- /dev/null +++ b/src/linear_string_map.c @@ -0,0 +1,68 @@ +#include +#include +#include + +#include "linear_string_map.h" + +struct __linear_string_map_t { + const char *key; + void *value; + struct __linear_string_map_t* next; +}; + +lsmap_t *lsmap_new() { + lsmap_t* lsmap = (lsmap_t*)malloc(sizeof(lsmap_t)); + lsmap->key = "dummy node"; + lsmap->next = NULL; + return lsmap; +} + +int lsmap_size(lsmap_t *lsmap) { + int size = 0; + while (lsmap->next != NULL) ++size; + return size; +} + +void lsmap_append(lsmap_t *lsmap, const char *key, void *value) { + while (lsmap->next != NULL) lsmap = lsmap->next; + lsmap->next = (lsmap_t*)malloc(sizeof(lsmap_t)); + lsmap->key = key; + lsmap->value = value; + lsmap = lsmap->next; + lsmap->key = "dummy node"; + lsmap->next = NULL; +} + +void* lsmap_search(lsmap_t *lsmap, const char *key) { + while (lsmap->next != NULL) { + if (strcmp(lsmap->key, key) == 0) { + return lsmap->value; + } + lsmap = lsmap->next; + } + return NULL; +} + +void lsmap_foreach_key(lsmap_t *lsmap, void (*f)(const char*)) { + while (lsmap->next != NULL) { + f(lsmap->key); + lsmap = lsmap->next; + } +} + +void lsmap_foreach_value(lsmap_t *lsmap, void (*f)(void*)) { + while (lsmap->next != NULL) { + f(lsmap->value); + lsmap = lsmap->next; + } +} + +void lsmap_destroy(lsmap_t *lsmap) { + while (lsmap->next != NULL) { + lsmap_t* freeme = lsmap; + lsmap = lsmap->next; + free(freeme); + } + free(lsmap); +} + diff --git a/src/linear_string_map.h b/src/linear_string_map.h new file mode 100644 index 0000000..2e2287e --- /dev/null +++ b/src/linear_string_map.h @@ -0,0 +1,13 @@ +// A simple linked list based dynamic sized associative map from const char* to +// void*. Designed to maximize ease of use instead of performance. Should be +// used in benchmarks and tests only, not to be distributed with the cmph +// runtime headers. + +typedef struct __linear_string_map_t lsmap_t; + +lsmap_t *lsmap_new(); +void lsmap_append(lsmap_t *lsmap, const char *key, void *value); +void* lsmap_search(lsmap_t *lsmap, const char *key); +void lsmap_foreach_key(lsmap_t* lsmap, void (*f)(const char*)); +void lsmap_foreach_value(lsmap_t* lsmap, void (*f)(void*)); +void lsmap_destroy(lsmap_t* lsmap);