Commit bef22f45 authored by Jim Harris's avatar Jim Harris Committed by Tomasz Zawadzki
Browse files

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: default avatarJim Harris <james.r.harris@intel.com>
Change-Id: I55b1587cdec2919973b488786d361042ca210606
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/7790


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: default avatarBen Walker <benjamin.walker@intel.com>
Community-CI: Mellanox Build Bot
parent 760452ee
Loading
Loading
Loading
Loading
+22 −3
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@
#include "spdk/rpc.h"
#include "spdk/bit_array.h"
#include "spdk/conf.h"
#include "spdk/zipf.h"

#define BDEVPERF_CONFIG_MAX_FILENAME 1024
#define BDEVPERF_CONFIG_UNDEFINED -1
@@ -91,6 +92,7 @@ static bool g_multithread_mode = false;
static int g_timeout_in_sec;
static struct spdk_conf *g_bdevperf_conf = NULL;
static const char *g_bdevperf_conf_file = NULL;
static double g_zipf_theta;

static struct spdk_cpuset g_all_cpuset;
static struct spdk_poller *g_perf_timer = NULL;
@@ -136,6 +138,7 @@ struct bdevperf_job {
	struct spdk_poller		*run_timer;
	struct spdk_poller		*reset_timer;
	struct spdk_bit_array		*outstanding;
	struct spdk_zipf		*zipf;
	TAILQ_HEAD(, bdevperf_task)	task_list;
};

@@ -406,7 +409,7 @@ bdevperf_test_done(void *ctx)
		if (job->verify) {
			spdk_bit_array_free(&job->outstanding);
		}

		spdk_zipf_free(&job->zipf);
		free(job->name);
		free(job);
	}
@@ -832,7 +835,9 @@ bdevperf_submit_single(struct bdevperf_job *job, struct bdevperf_task *task)
{
	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;
	} else {
		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;
	}

	if (job->is_random && g_zipf_theta > 0) {
		job->zipf = spdk_zipf_create(job->size_in_ios, g_zipf_theta, 0);
	}

	if (job->verify) {
		job->outstanding = spdk_bit_array_create(job->size_in_ios);
		if (job->outstanding == NULL) {
@@ -1935,6 +1944,15 @@ bdevperf_parse_arg(int ch, char *arg)
		g_continue_on_failure = true;
	} else if (ch == 'j') {
		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 {
		tmp = spdk_strtoll(optarg, 10);
		if (tmp < 0) {
@@ -1992,6 +2010,7 @@ bdevperf_usage(void)
	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(" -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                        start bdevperf, but wait for RPC to start tests\n");
	printf(" -X                        abort timed out I/O\n");
@@ -2102,7 +2121,7 @@ main(int argc, char **argv)
	opts.rpc_addr = NULL;
	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)) !=
	    SPDK_APP_PARSE_ARGS_SUCCESS) {
		return rc;