bdevperf: add -F option for zipf distribution
Currently this will only support a global setting that must be set on the command line. We can make it per-job later, but will require adding float support to the conf library. Tested by running bdevperf with some malloc bdevs. Performance with low theta values (i.e. 0.2) are almost identical to random w/o zipf. But higher zipf values start to show better performance, because we get more hits on data that is already in the CPU cache. Signed-off-by: Jim Harris <james.r.harris@intel.com> Change-Id: I55b1587cdec2919973b488786d361042ca210606 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/7790 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Community-CI: Mellanox Build Bot
This commit is contained in:
parent
760452eefe
commit
bef22f45e7
@ -45,6 +45,7 @@
|
|||||||
#include "spdk/rpc.h"
|
#include "spdk/rpc.h"
|
||||||
#include "spdk/bit_array.h"
|
#include "spdk/bit_array.h"
|
||||||
#include "spdk/conf.h"
|
#include "spdk/conf.h"
|
||||||
|
#include "spdk/zipf.h"
|
||||||
|
|
||||||
#define BDEVPERF_CONFIG_MAX_FILENAME 1024
|
#define BDEVPERF_CONFIG_MAX_FILENAME 1024
|
||||||
#define BDEVPERF_CONFIG_UNDEFINED -1
|
#define BDEVPERF_CONFIG_UNDEFINED -1
|
||||||
@ -91,6 +92,7 @@ static bool g_multithread_mode = false;
|
|||||||
static int g_timeout_in_sec;
|
static int g_timeout_in_sec;
|
||||||
static struct spdk_conf *g_bdevperf_conf = NULL;
|
static struct spdk_conf *g_bdevperf_conf = NULL;
|
||||||
static const char *g_bdevperf_conf_file = NULL;
|
static const char *g_bdevperf_conf_file = NULL;
|
||||||
|
static double g_zipf_theta;
|
||||||
|
|
||||||
static struct spdk_cpuset g_all_cpuset;
|
static struct spdk_cpuset g_all_cpuset;
|
||||||
static struct spdk_poller *g_perf_timer = NULL;
|
static struct spdk_poller *g_perf_timer = NULL;
|
||||||
@ -136,6 +138,7 @@ struct bdevperf_job {
|
|||||||
struct spdk_poller *run_timer;
|
struct spdk_poller *run_timer;
|
||||||
struct spdk_poller *reset_timer;
|
struct spdk_poller *reset_timer;
|
||||||
struct spdk_bit_array *outstanding;
|
struct spdk_bit_array *outstanding;
|
||||||
|
struct spdk_zipf *zipf;
|
||||||
TAILQ_HEAD(, bdevperf_task) task_list;
|
TAILQ_HEAD(, bdevperf_task) task_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -406,7 +409,7 @@ bdevperf_test_done(void *ctx)
|
|||||||
if (job->verify) {
|
if (job->verify) {
|
||||||
spdk_bit_array_free(&job->outstanding);
|
spdk_bit_array_free(&job->outstanding);
|
||||||
}
|
}
|
||||||
|
spdk_zipf_free(&job->zipf);
|
||||||
free(job->name);
|
free(job->name);
|
||||||
free(job);
|
free(job);
|
||||||
}
|
}
|
||||||
@ -832,7 +835,9 @@ bdevperf_submit_single(struct bdevperf_job *job, struct bdevperf_task *task)
|
|||||||
{
|
{
|
||||||
uint64_t offset_in_ios;
|
uint64_t offset_in_ios;
|
||||||
|
|
||||||
if (job->is_random) {
|
if (job->zipf) {
|
||||||
|
offset_in_ios = spdk_zipf_generate(job->zipf);
|
||||||
|
} else if (job->is_random) {
|
||||||
offset_in_ios = rand_r(&job->seed) % job->size_in_ios;
|
offset_in_ios = rand_r(&job->seed) % job->size_in_ios;
|
||||||
} else {
|
} else {
|
||||||
offset_in_ios = job->offset_in_ios++;
|
offset_in_ios = job->offset_in_ios++;
|
||||||
@ -1298,6 +1303,10 @@ bdevperf_construct_job(struct spdk_bdev *bdev, struct job_config *config,
|
|||||||
job->ios_base = 0;
|
job->ios_base = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (job->is_random && g_zipf_theta > 0) {
|
||||||
|
job->zipf = spdk_zipf_create(job->size_in_ios, g_zipf_theta, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (job->verify) {
|
if (job->verify) {
|
||||||
job->outstanding = spdk_bit_array_create(job->size_in_ios);
|
job->outstanding = spdk_bit_array_create(job->size_in_ios);
|
||||||
if (job->outstanding == NULL) {
|
if (job->outstanding == NULL) {
|
||||||
@ -1935,6 +1944,15 @@ bdevperf_parse_arg(int ch, char *arg)
|
|||||||
g_continue_on_failure = true;
|
g_continue_on_failure = true;
|
||||||
} else if (ch == 'j') {
|
} else if (ch == 'j') {
|
||||||
g_bdevperf_conf_file = optarg;
|
g_bdevperf_conf_file = optarg;
|
||||||
|
} else if (ch == 'F') {
|
||||||
|
char *endptr;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
g_zipf_theta = strtod(optarg, &endptr);
|
||||||
|
if (errno || optarg == endptr || g_zipf_theta < 0) {
|
||||||
|
fprintf(stderr, "Illegal zipf theta value %s\n", optarg);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
tmp = spdk_strtoll(optarg, 10);
|
tmp = spdk_strtoll(optarg, 10);
|
||||||
if (tmp < 0) {
|
if (tmp < 0) {
|
||||||
@ -1992,6 +2010,7 @@ bdevperf_usage(void)
|
|||||||
printf(" -S <period> show performance result in real time every <period> seconds\n");
|
printf(" -S <period> show performance result in real time every <period> seconds\n");
|
||||||
printf(" -T <bdev> bdev to run against. Default: all available bdevs.\n");
|
printf(" -T <bdev> bdev to run against. Default: all available bdevs.\n");
|
||||||
printf(" -f continue processing I/O even after failures\n");
|
printf(" -f continue processing I/O even after failures\n");
|
||||||
|
printf(" -F <zipf theta> use zipf distribution for random I/O\n");
|
||||||
printf(" -Z enable using zcopy bdev API for read or write I/O\n");
|
printf(" -Z enable using zcopy bdev API for read or write I/O\n");
|
||||||
printf(" -z start bdevperf, but wait for RPC to start tests\n");
|
printf(" -z start bdevperf, but wait for RPC to start tests\n");
|
||||||
printf(" -X abort timed out I/O\n");
|
printf(" -X abort timed out I/O\n");
|
||||||
@ -2102,7 +2121,7 @@ main(int argc, char **argv)
|
|||||||
opts.rpc_addr = NULL;
|
opts.rpc_addr = NULL;
|
||||||
opts.shutdown_cb = spdk_bdevperf_shutdown_cb;
|
opts.shutdown_cb = spdk_bdevperf_shutdown_cb;
|
||||||
|
|
||||||
if ((rc = spdk_app_parse_args(argc, argv, &opts, "Zzfq:o:t:w:k:CM:P:S:T:Xj:", NULL,
|
if ((rc = spdk_app_parse_args(argc, argv, &opts, "Zzfq:o:t:w:k:CF:M:P:S:T:Xj:", NULL,
|
||||||
bdevperf_parse_arg, bdevperf_usage)) !=
|
bdevperf_parse_arg, bdevperf_usage)) !=
|
||||||
SPDK_APP_PARSE_ARGS_SUCCESS) {
|
SPDK_APP_PARSE_ARGS_SUCCESS) {
|
||||||
return rc;
|
return rc;
|
||||||
|
Loading…
Reference in New Issue
Block a user