static volatile int wait_;
static volatile int stop_;
-static long num_threads_;
+static int num_threads_;
+static int duration_;
static map_t *map_;
static int get_range_;
static int put_range_;
-static int num_keys_;
+static size_t num_keys_;
static map_key_t *keys_ = NULL;
-static uint64_t times_[MAX_NUM_THREADS] = {};
static int ops_[MAX_NUM_THREADS] = {};
+#define FOO (1ULL << 20)
+
void *worker (void *arg) {
int tid = (int)(size_t)arg;
uint64_t s = nbd_rand_seed(tid);
(void)SYNC_ADD(&wait_, -1);
do {} while (wait_);
- uint64_t t1 = rdtsc();
-
while (!stop_) {
- int r = nbd_next_rand(&s);
- int x = r & ( (1 << 20) - 1 );
- int i = nbd_next_rand(&s) & (num_keys_ - 1);
- map_key_t key = keys_[i];
+ map_key_t key = keys_[ nbd_next_rand(&s) & (num_keys_ - 1) ];
+ uint32_t x = nbd_next_rand(&s) & (FOO - 1);
if (x < get_range_) {
- map_val_t val = map_get(map_, key);
+#ifndef NDEBUG
+ map_val_t val =
+#endif
+ map_get(map_, key);
#ifdef TEST_STRING_KEYS
ASSERT(val == DOES_NOT_EXIST || ns_cmp((nstring_t *)key, (nstring_t *)val) == 0);
#else
rcu_update();
}
- times_[tid] = rdtsc() - t1;
ops_[tid] = get_ops + put_ops + del_ops;
return NULL;
}
-void run_test (void) {
+int run_test (void) {
+ int ops;
wait_ = num_threads_ + 1;
// Quicky sanity check
do { /* nothing */ } while (wait_ != 1);
wait_ = 0;
- sleep(2);
+ sleep(duration_);
stop_ = 1;
for (int i = 0; i < num_threads_; ++i) {
pthread_join(thread[i], NULL);
}
+ ops = 0;
+ for (int i = 0; i < num_threads_; ++i) {
+ ops += ops_[i];
+ }
+ return ops;
}
int main (int argc, char **argv) {
char* program_name = argv[0];
- if (argc > 2) {
+ if (argc > 3) {
fprintf(stderr, "Usage: %s num_threads\n", program_name);
return -1;
}
num_threads_ = 2;
- if (argc == 2)
+ if (argc > 1)
{
errno = 0;
num_threads_ = strtol(argv[1], NULL, 10);
}
}
+ int table_scale = 12;
+ if (argc > 2) {
+ table_scale = strtol(argv[2], NULL, 10);
+ if (errno) {
+ fprintf(stderr, "%s: Invalid argument for the scale of the collection\n", program_name);
+ return -1;
+ }
+ table_scale = strtol(argv[2], NULL, 10);
+ if (table_scale < 0 || table_scale > 31) {
+ fprintf(stderr, "%s: The scale of the collection must be between 0 and 31\n", program_name);
+ return -1;
+ }
+ }
+
- int table_scale = 10;
- int read_ratio = 95;
- get_range_ = (read_ratio << 20) / 100;
- put_range_ = (((1 << 20) - get_range_) >> 1) + get_range_;
+ int read_ratio = 90;
+ int put_ratio = 50;
+ get_range_ = (int)((double)FOO / 100 * read_ratio);
+ put_range_ = get_range_ + (int)(((double)FOO - get_range_) / 100 * put_ratio);
- static const map_impl_t *map_types[] = { &MAP_IMPL_HT };
+ static const map_impl_t *map_types[] = { &MAP_IMPL_SL };
for (int i = 0; i < sizeof(map_types)/sizeof(*map_types); ++i) {
#ifdef TEST_STRING_KEYS
map_ = map_alloc(map_types[i], &DATATYPE_NSTRING);
#endif
// Do some warmup
- num_keys_ = 1 << table_scale;
+ num_keys_ = 1ULL << table_scale;
keys_ = nbd_malloc(sizeof(map_key_t) * num_keys_);
- for (int j = 0; j < num_keys_; ++j) {
+ ASSERT(keys_ != NULL);
+ for (uint64_t j = 0; j < num_keys_; ++j) {
#ifdef TEST_STRING_KEYS
char tmp[64];
snprintf(tmp, sizeof(tmp), "%dabc%d", j, j*17+123);
#endif
}
- struct timeval tv1, tv2;
- gettimeofday(&tv1, NULL);
-
+ duration_ = 10;
int num_trials = 1;
+ int ops = 0;
for (int i = 0; i < num_trials; ++i) {
- run_test();
+ ops += run_test();
}
+ double ops_per_sec = ops / num_trials / duration_;
- gettimeofday(&tv2, NULL);
- int ms = (int)(1000000*(tv2.tv_sec - tv1.tv_sec) + tv2.tv_usec - tv1.tv_usec) / 1000;
- map_print(map_);
- printf("Th:%ld Time:%dms\n\n", num_threads_, ms);
+ //map_print(map_);
+ printf("Threads:%-2d Size:2^%-2d Mops/Sec:%-4.3g per-thread:%-4.3g\n\n",
+ num_threads_, table_scale, ops_per_sec/1000000, ops_per_sec/num_threads_/1000000);
fflush(stdout);
map_free(map_);