diff --git a/src/sb_rand.c b/src/sb_rand.c index 563b566e3..ecd987813 100644 --- a/src/sb_rand.c +++ b/src/sb_rand.c @@ -82,19 +82,14 @@ static sb_arg_t rand_args[] = static rand_dist_t rand_type; /* pointer to the default PRNG as defined by --rand-type */ -static uint32_t (*rand_func)(uint32_t, uint32_t); +static uint64_t (*rand_func)(uint64_t, uint64_t); static unsigned int rand_iter; -static unsigned int rand_pct; -static unsigned int rand_res; /* Pre-computed FP constants to avoid unnecessary conversions and divisions at runtime. */ static double rand_iter_mult; -static double rand_pct_mult; -static double rand_pct_2_mult; -static double rand_res_mult; /* parameters for Pareto distribution */ static double pareto_h; /* parameter h */ @@ -106,15 +101,15 @@ static double zipf_s; static double zipf_hIntegralX1; /* Unique sequence generator state */ -static uint32_t rand_unique_index CK_CC_CACHELINE; -static uint32_t rand_unique_offset; +static uint64_t rand_unique_index CK_CC_CACHELINE; +static uint64_t rand_unique_offset; extern inline uint64_t sb_rand_uniform_uint64(void); extern inline double sb_rand_uniform_double(void); extern inline uint64_t xoroshiro_rotl(const uint64_t, int); extern inline uint64_t xoroshiro_next(uint64_t s[2]); -static void rand_unique_seed(uint32_t index, uint32_t offset); +static void rand_unique_seed(uint64_t index, uint64_t offset); /* Helper functions for the Zipfian distribution */ static double hIntegral(double x, double e); @@ -165,16 +160,9 @@ int sb_rand_init(void) return 1; } - rand_iter = sb_get_value_int("rand-spec-iter"); + rand_iter = 12; rand_iter_mult = 1.0 / rand_iter; - rand_pct = sb_get_value_int("rand-spec-pct"); - rand_pct_mult = rand_pct / 100.0; - rand_pct_2_mult = rand_pct / 200.0; - - rand_res = sb_get_value_int("rand-spec-res"); - rand_res_mult = 100.0 / (100.0 - rand_res); - pareto_h = sb_get_value_double("rand-pareto-h"); pareto_power = log(pareto_h) / log(1.0-pareto_h); @@ -227,21 +215,21 @@ void sb_rand_thread_init(void) with the --rand-type command line option */ -uint32_t sb_rand_default(uint32_t a, uint32_t b) +uint64_t sb_rand_default(uint64_t a, uint64_t b) { return rand_func(a,b); } /* uniform distribution */ -uint32_t sb_rand_uniform(uint32_t a, uint32_t b) +uint64_t sb_rand_uniform(uint64_t a, uint64_t b) { return a + sb_rand_uniform_double() * (b - a + 1); } /* gaussian distribution */ -uint32_t sb_rand_gaussian(uint32_t a, uint32_t b) +uint64_t sb_rand_gaussian(uint64_t a, uint64_t b) { double sum; double t; @@ -251,14 +239,14 @@ uint32_t sb_rand_gaussian(uint32_t a, uint32_t b) for(i=0, sum=0; i < rand_iter; i++) sum += sb_rand_uniform_double() * t; - return a + (uint32_t) (sum * rand_iter_mult) ; + return a + (uint64_t) (sum * rand_iter_mult) ; } /* Pareto distribution */ -uint32_t sb_rand_pareto(uint32_t a, uint32_t b) +uint64_t sb_rand_pareto(uint64_t a, uint64_t b) { - return a + (uint32_t) ((b - a + 1) * + return a + (uint64_t) ((b - a + 1) * pow(sb_rand_uniform_double(), pareto_power)); } @@ -285,10 +273,10 @@ void sb_rand_str(const char *fmt, char *buf) the number of characters written into the buffer. */ -uint32_t sb_rand_varstr(char *buf, uint32_t min_len, uint32_t max_len) +uint64_t sb_rand_varstr(char *buf, uint64_t min_len, uint64_t max_len) { unsigned int i; - uint32_t num_chars; + uint64_t num_chars; if (max_len == 0) { return 0; /* we can't be sure buf is long enough to populate, so be safe */ } @@ -310,19 +298,19 @@ uint32_t sb_rand_varstr(char *buf, uint32_t min_len, uint32_t max_len) https://github.com/preshing/RandomSequence */ -static uint32_t rand_unique_permute(uint32_t x) +static uint64_t rand_unique_permute(uint64_t x) { - static const uint32_t prime = UINT32_C(4294967291); + static const uint64_t prime = UINT32_C(4294967291); if (x >= prime) return x; /* The 5 integers out of range are mapped to themselves. */ - uint32_t residue = ((uint64_t) x * x) % prime; + uint64_t residue = ((uint64_t) x * x) % prime; return (x <= prime / 2) ? residue : prime - residue; } -static void rand_unique_seed(uint32_t index, uint32_t offset) +static void rand_unique_seed(uint64_t index, uint64_t offset) { rand_unique_index = rand_unique_permute(rand_unique_permute(index) + 0x682f0161); @@ -332,9 +320,9 @@ static void rand_unique_seed(uint32_t index, uint32_t offset) /* This is safe to be called concurrently from multiple threads */ -uint32_t sb_rand_unique(void) +uint64_t sb_rand_unique(void) { - uint32_t index = ck_pr_faa_32(&rand_unique_index, 1); + uint64_t index = ck_pr_faa_64(&rand_unique_index, 1); return rand_unique_permute((rand_unique_permute(index) + rand_unique_offset) ^ 0x5bf03635); @@ -352,7 +340,7 @@ uint32_t sb_rand_unique(void) and Computer Simulation, (TOMACS) 6.3 (1996): 169-184. */ -static uint32_t sb_rand_zipfian_int(uint32_t n, double e, double s, +static uint64_t sb_rand_zipfian_int(uint64_t n, double e, double s, double hIntegralX1) { /* @@ -385,7 +373,7 @@ static uint32_t sb_rand_zipfian_int(uint32_t n, double e, double s, /* u is uniformly distributed in (hIntegralX1, hIntegralNumberOfElements] */ double x = hIntegralInverse(u, e); - uint32_t k = (uint32_t) (x + 0.5); + uint64_t k = (uint64_t) (x + 0.5); /* Limit k to the range [1, numberOfElements] if it would be outside due to @@ -449,7 +437,7 @@ static uint32_t sb_rand_zipfian_int(uint32_t n, double e, double s, } } -uint32_t sb_rand_zipfian(uint32_t a, uint32_t b) +uint64_t sb_rand_zipfian(uint64_t a, uint64_t b) { /* sb_rand_zipfian_int() returns a number in the range [1, b - a + 1] */ return a + diff --git a/src/sb_rand.h b/src/sb_rand.h index 6cb3dab2d..4dc2d9542 100644 --- a/src/sb_rand.h +++ b/src/sb_rand.h @@ -62,13 +62,13 @@ void sb_rand_done(void); void sb_rand_thread_init(void); /* Generator functions */ -uint32_t sb_rand_default(uint32_t, uint32_t); -uint32_t sb_rand_uniform(uint32_t, uint32_t); -uint32_t sb_rand_gaussian(uint32_t, uint32_t); -uint32_t sb_rand_pareto(uint32_t, uint32_t); -uint32_t sb_rand_zipfian(uint32_t, uint32_t); -uint32_t sb_rand_unique(void); +uint64_t sb_rand_default(uint64_t, uint64_t); +uint64_t sb_rand_uniform(uint64_t, uint64_t); +uint64_t sb_rand_gaussian(uint64_t, uint64_t); +uint64_t sb_rand_pareto(uint64_t, uint64_t); +uint64_t sb_rand_zipfian(uint64_t, uint64_t); +uint64_t sb_rand_unique(void); void sb_rand_str(const char *, char *); -uint32_t sb_rand_varstr(char *, uint32_t, uint32_t); +uint64_t sb_rand_varstr(char *, uint64_t, uint64_t); #endif /* SB_RAND_H */ diff --git a/src/tests/memory/sb_memory.c b/src/tests/memory/sb_memory.c index 27ecae843..9678aa804 100644 --- a/src/tests/memory/sb_memory.c +++ b/src/tests/memory/sb_memory.c @@ -22,6 +22,7 @@ #include "sysbench.h" #include "sb_rand.h" +#include "sb_counter.h" #ifdef HAVE_SYS_IPC_H # include @@ -83,6 +84,7 @@ static sb_test_t memory_test = static ssize_t memory_block_size; static long long memory_total_size; +static long long memory_total_size_per_thread; static unsigned int memory_scope; static unsigned int memory_oper; static unsigned int memory_access_rnd; @@ -91,6 +93,7 @@ static unsigned int memory_hugetlb; #endif static ssize_t max_offset; +static ssize_t iterations; /* Arrays of per-thread buffers and event counters */ static size_t **buffers; @@ -127,6 +130,10 @@ int memory_init(void) max_offset = memory_block_size / SIZEOF_SIZE_T - 1; memory_total_size = sb_get_value_size("memory-total-size"); + memory_total_size_per_thread = memory_total_size / sb_globals.threads; + + iterations = (memory_total_size_per_thread > memory_block_size ? + memory_block_size : memory_total_size_per_thread) / SIZEOF_SIZE_T - 1; s = sb_get_value_string("memory-scope"); if (!strcmp(s, "global")) @@ -216,7 +223,9 @@ int memory_init(void) } thread_counters[i] = - memory_total_size / memory_block_size / sb_globals.threads; + memory_total_size_per_thread / + (memory_total_size_per_thread > memory_block_size ? + memory_block_size : memory_total_size_per_thread); } switch (memory_oper) { @@ -283,7 +292,7 @@ int event_rnd_none(sb_event_t *req, int tid) (void) req; /* unused */ (void) tid; /* unused */ - for (ssize_t i = 0; i <= max_offset; i++) + for (ssize_t i = 0; i <= iterations; i++) { size_t offset = (volatile size_t) sb_rand_default(0, max_offset); (void) offset; /* unused */ @@ -297,11 +306,14 @@ int event_rnd_read(sb_event_t *req, int tid) { (void) req; /* unused */ - for (ssize_t i = 0; i <= max_offset; i++) + for (ssize_t i = 0; i <= iterations; i++) { size_t offset = (size_t) sb_rand_default(0, max_offset); size_t val = SIZE_T_LOAD(buffers[tid] + offset); (void) val; /* unused */ + if (sb_globals.report_interval) { + sb_counter_inc(tid, SB_CNT_READ); + } } return 0; @@ -312,10 +324,13 @@ int event_rnd_write(sb_event_t *req, int tid) { (void) req; /* unused */ - for (ssize_t i = 0; i <= max_offset; i++) + for (ssize_t i = 0; i <= iterations; i++) { size_t offset = (size_t) sb_rand_default(0, max_offset); SIZE_T_STORE(buffers[tid] + offset, i); + if (sb_globals.report_interval) { + sb_counter_inc(tid, SB_CNT_WRITE); + } } return 0; @@ -326,7 +341,7 @@ int event_seq_none(sb_event_t *req, int tid) { (void) req; /* unused */ - for (size_t *buf = buffers[tid], *end = buf + max_offset; buf <= end; buf++) + for (size_t *buf = buffers[tid], *end = buf + iterations; buf <= end; buf++) { ck_pr_barrier(); /* nop */ @@ -340,10 +355,13 @@ int event_seq_read(sb_event_t *req, int tid) { (void) req; /* unused */ - for (size_t *buf = buffers[tid], *end = buf + max_offset; buf < end; buf++) + for (size_t *buf = buffers[tid], *end = buf + iterations; buf < end; buf++) { size_t val = SIZE_T_LOAD(buf); (void) val; /* unused */ + if (sb_globals.report_interval) { + sb_counter_inc(tid, SB_CNT_READ); + } } return 0; @@ -354,9 +372,12 @@ int event_seq_write(sb_event_t *req, int tid) { (void) req; /* unused */ - for (size_t *buf = buffers[tid], *end = buf + max_offset; buf < end; buf++) + for (size_t *buf = buffers[tid], *end = buf + iterations; buf < end; buf++) { SIZE_T_STORE(buf, (size_t) tid); + if (sb_globals.report_interval) { + sb_counter_inc(tid, SB_CNT_WRITE); + } } return 0; @@ -412,9 +433,10 @@ void memory_print_mode(void) void memory_report_intermediate(sb_stat_t *stat) { const double megabyte = 1024.0 * 1024.0; + uint64_t events = stat->writes ? stat->writes : stat->reads; log_timestamp(LOG_NOTICE, stat->time_total, "%4.2f MiB/sec", - stat->events * memory_block_size / megabyte / + events * SIZEOF_SIZE_T / megabyte / stat->time_interval); } @@ -431,7 +453,7 @@ void memory_report_cumulative(sb_stat_t *stat) if (memory_oper != SB_MEM_OP_NONE) { - const double mb = stat->events * memory_block_size / megabyte; + const double mb = memory_total_size / megabyte; log_text(LOG_NOTICE, "%4.2f MiB transferred (%4.2f MiB/sec)\n", mb, mb / stat->time_interval); }