the job to exit. The same format as rate is used for read vs
write separation.
+rate_poisson=bool When rate limited, try to simulate request flow under
+ Poisson process (instead of even distribution). Default: false.
+
latency_target=int If set, fio will attempt to find the max performance
point that the given workload will run at while maintaining a
latency below this target. The values is given in microseconds.
bytes = td->rate_io_issue_bytes[ddir];
bps = td->rate_bps[ddir];
- if (td->o.poisson_request) {
+ if (td->o.poisson_rate) {
iops = bps / td->o.bs[ddir];
- td->last_usec += (long long)(1000000 / iops) *
- (-logf(((float)rand() + 1) / ((float)RAND_MAX + 1)));
+ td->last_usec += (int64_t) (1000000 / iops) *
+ -logf(__rand_0_1(&td->poisson_state));
return td->last_usec;
} else if (bps) {
secs = bytes / bps;
remainder = bytes % bps;
return remainder * 1000000 / bps + secs * 1000000;
- } else
- return 0;
+ }
+
+ return 0;
}
/*
o->per_job_logs = le32_to_cpu(top->per_job_logs);
o->trim_backlog = le64_to_cpu(top->trim_backlog);
+ o->poisson_rate = le32_to_cpu(top->poisson_rate);
for (i = 0; i < FIO_IO_U_LIST_MAX_LEN; i++)
o->percentile_list[i].u.f = fio_uint64_to_double(le64_to_cpu(top->percentile_list[i].u.i));
top->trim_backlog = __cpu_to_le64(o->trim_backlog);
top->offset_increment = __cpu_to_le64(o->offset_increment);
top->number_ios = __cpu_to_le64(o->number_ios);
+ top->poisson_rate = cpu_to_le32(o->poisson_rate);
for (i = 0; i < FIO_IO_U_LIST_MAX_LEN; i++)
top->percentile_list[i].u.i = __cpu_to_le64(fio_double_to_uint64(o->percentile_list[i].u.f));
If this rate of I/O is not met, the job will exit. The same format as \fBrate\fR
is used for read vs write separation.
.TP
-.BI poisson \fR=\fPbool
-When rate limited, try simulate request flow under Poisson process (instead
+.BI rate_poisson \fR=\fPbool
+When rate limited, try to simulate request flow under Poisson process (instead
of even distribution). Default: false.
.TP
.BI ratecycle \fR=\fPint
FIO_RAND_SEQ_RAND_TRIM_OFF,
FIO_RAND_START_DELAY,
FIO_DEDUPE_OFF,
+ FIO_RAND_POISSON_OFF,
FIO_RAND_NR_OFFS,
};
unsigned long rate_blocks[DDIR_RWDIR_CNT];
unsigned long rate_io_issue_bytes[DDIR_RWDIR_CNT];
struct timeval lastrate[DDIR_RWDIR_CNT];
- unsigned long long last_usec;
+ int64_t last_usec;
+ struct frand_state poisson_state;
/*
* Enforced rate submission/completion workqueue
init_rand_seed(&td->file_size_state, td->rand_seeds[FIO_RAND_FILE_SIZE_OFF], use64);
init_rand_seed(&td->trim_state, td->rand_seeds[FIO_RAND_TRIM_OFF], use64);
init_rand_seed(&td->delay_state, td->rand_seeds[FIO_RAND_START_DELAY], use64);
+ init_rand_seed(&td->poisson_state, td->rand_seeds[FIO_RAND_POISSON_OFF], 0);
if (!td_random(td))
return;
return __rand32(&state->state32);
}
+static inline double __rand_0_1(struct frand_state *state)
+{
+ if (state->use64) {
+ uint64_t val = __rand64(&state->state64);
+
+ return (double) val / (FRAND64_MAX + 1.0);
+ } else {
+ uint32_t val = __rand32(&state->state32);
+
+ return (double) val / (FRAND32_MAX + 1.0);
+ }
+}
+
extern void init_rand(struct frand_state *, int);
extern void init_rand_seed(struct frand_state *, unsigned int seed, int);
extern void __fill_random_buf(void *buf, unsigned int len, unsigned long seed);
.group = FIO_OPT_G_RATE,
},
{
- .name = "poisson",
+ .name = "rate_poisson",
.lname = "simulate requests under Poisson process",
.type = FIO_OPT_BOOL,
- .off1 = td_var_offset(poisson_request),
- .help = "with rate limit, try simulate requests that follow Poisson process",
+ .off1 = td_var_offset(poisson_rate),
+ .help = "With rate limit, simulate requests that follow Poisson process",
.def = "0",
+ .parent = "rate",
.hide = 1,
.category = FIO_OPT_C_IO,
.group = FIO_OPT_G_RATE,
};
enum {
- FIO_SERVER_VER = 47,
+ FIO_SERVER_VER = 48,
FIO_SERVER_MAX_FRAGMENT_PDU = 1024,
FIO_SERVER_MAX_CMD_MB = 2048,
unsigned int io_submit_mode;
unsigned int rate_iops[DDIR_RWDIR_CNT];
unsigned int rate_iops_min[DDIR_RWDIR_CNT];
- unsigned int poisson_request;
+ unsigned int poisson_rate;
char *ioscheduler;
uint32_t io_submit_mode;
uint32_t rate_iops[DDIR_RWDIR_CNT];
uint32_t rate_iops_min[DDIR_RWDIR_CNT];
- uint32_t poisson_request;
+ uint32_t poisson_rate;
uint32_t padding_0; /* for alignment assert */
uint8_t ioscheduler[FIO_TOP_STR_MAX];