Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for sb_rand and sb_memory and supported parameters extension for memory test #455

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 22 additions & 34 deletions src/sb_rand.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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);
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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;
Expand All @@ -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));
}

Expand All @@ -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 */
}
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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)
{
/*
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 +
Expand Down
14 changes: 7 additions & 7 deletions src/sb_rand.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
40 changes: 31 additions & 9 deletions src/tests/memory/sb_memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include "sysbench.h"
#include "sb_rand.h"
#include "sb_counter.h"

#ifdef HAVE_SYS_IPC_H
# include <sys/ipc.h>
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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"))
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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 */
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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 */
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
}

Expand All @@ -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);
}
Expand Down