Exemple #1
0
void ia_doer_init(iadoer *doer, int nth, long benchmask, int key_space, int key_sequence)
{
	assert(benchmask);
	doer->ctx = NULL;
	doer->nth = nth;
	doer->benchmask = benchmask;
	doer->key_space = key_space;
	doer->key_sequence = key_sequence;

	if (benchmask) {
		char line[1024], *s;
		iabenchmark bench;
		s = line;
		for(bench = IA_SET; bench < IA_MAX; ++bench)
			if (benchmask & (1l << bench))
				s += snprintf(s, line + sizeof(line) - s, "%s%s",
				s != line ? ", " : "",
				ia_benchmarkof(bench));

		ia_log("doer.%d: {%s}, key-space %d, key-sequence %d",
			doer->nth, line, key_space, key_sequence);
	}

	ia_kvpool_init(&doer->pool, ioarena.conf.ksize, ioarena.conf.vsize, doer->key_space, doer->key_sequence, ioarena.conf.count);
	ia_kvpool_fill(&doer->pool, ioarena.conf.count, 2);
	ia_histogram_init(&doer->hg);
	__sync_fetch_and_add(&ioarena.doers_count, 1);
}
Exemple #2
0
int ia_init(ia *a, int argc, char **argv)
{
	int rc;

	ia_log("IOARENA (embedded storage benchmarking)\n");

	rc = ia_configinit(&a->conf);
	if (rc == -1)
		return -1;
	rc = ia_configparse(&a->conf, argc, argv);
	if (rc == -1 || rc == 1)
		return rc;
	ia_configprint(&a->conf);
	a->driver = a->conf.driver_if;

	mkdir(ioarena.conf.path, 0755);
	snprintf(a->datadir, sizeof(a->datadir), "%s/%s", ioarena.conf.path, a->driver->name);
	mkdir(a->datadir, 0755);

	iarusage before_open;
	rc = ia_get_rusage(&before_open, a->datadir);
	if (rc)
		return -1;

	a->before_open_ram = before_open.ram;
	rc = a->driver->open(a->datadir);
	if (rc == -1)
		return -1;
	return 0;
}
Exemple #3
0
void ia_kvpool_fill(struct iakvpool *pool, size_t nbandles, size_t nelem)
{
	size_t i, j, bytes = nbandles * nelem * (pool->vsize + pool->ksize);
	char* dst = realloc(pool->flat, bytes);
	if (! dst) {
		ia_log("error: out of memory");
		ia_fatal(__func__);
	}

	pool->flat = dst;
	for (i = 0; i < nbandles; ++i) {
		uint64_t point = pool->space + pool->serial;
		pool->serial = (pool->serial + 1) % pool->period;

		for (j = 0; j < nelem; ++j) {
			dst = kv_rnd(&point, dst, !ioarena.conf.binary, pool->ksize);
			if (pool->vsize)
				dst = kv_rnd(&point, dst, !ioarena.conf.binary, pool->vsize);
		}
	}

	assert(dst == pool->flat + bytes);
	pool->pos = 0;
	pool->power = bytes;
}
Exemple #4
0
static void ia_sync_fihish(ia *a)
{
	int rc = pthread_barrier_wait(&a->barrier_fihish);
	if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) {
		ia_log("error: pthread_barrier_wait %s (%d)", strerror(rc), rc);
		ia_fatal(__func__);
	}
}
Exemple #5
0
static void ia_sync_start(ia *a)
{
#ifdef _POSIX_PRIORITY_SCHEDULING
	sched_yield();
#elif defined(__APPLE__) || defined(__MACH__)
	pthread_yield_np();
#else
	pthread_yield();
#endif
	int rc = pthread_barrier_wait(&a->barrier_start);
	if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) {
		ia_log("error: pthread_barrier_wait %s (%d)", strerror(rc), rc);
		ia_fatal(__func__);
	}
}
Exemple #6
0
static FILE* csv_create(const iaconfig *config, const char* item)
{
	FILE* f = NULL;

	if(config->csv_prefix) {
		char path[PATH_MAX];
		snprintf(path, sizeof(path),
				 "%s%s_%s_%s.csv", config->csv_prefix, config->driver, ia_syncmode2str(config->syncmode), item);
		f = fopen(path, "w");
		if (! f)
			ia_log("error: %s, %s (%d)", path, strerror(errno), errno);
	}

	return f;
}
Exemple #7
0
static void ia_keynotfound(iadoer *doer, const char *op, iakv *k)
{
	ia_log("error: key %s not found (%s, #%d, %d+%d)",
		   k->k, op, doer->nth, doer->key_space, doer->key_sequence);
}
Exemple #8
0
int ia_run(ia *a)
{
	long set_rd = 0;
	long set_wr = 0;
	iabenchmark bench;
	for (bench = IA_SET; bench < IA_MAX; bench++) {
		if (! a->conf.benchmark_list[bench])
			continue;

		ia_histogram_enable(bench);
		if (bench == IA_ITERATE || bench == IA_GET)
			set_rd |= 1l << bench;
		else
			set_wr |= 1l << bench;
	}

	if ((set_rd | set_wr) == 0)
		return 0;
	if (a->conf.rthr && set_rd == 0)
		a->conf.rthr = 0;
	if (a->conf.wthr && set_wr == 0)
		a->conf.wthr = 0;

	int key_nsectors = 1;
	if (key_nsectors < a->conf.rthr)
		key_nsectors = a->conf.rthr;
	if (key_nsectors < a->conf.wthr)
		key_nsectors = a->conf.wthr;

	int key_nspaces = 1;
	if (key_nspaces < a->conf.wthr)
		key_nspaces = a->conf.wthr;
	if (set_wr & bench_mask_2keyspace)
		key_nspaces	+= key_nspaces;

	int rc = ia_kvgen_setup(!ioarena.conf.binary, ioarena.conf.ksize,
		key_nspaces, key_nsectors, ioarena.conf.count, ioarena.conf.kvseed);
	if (rc) {
		ia_log("error: key-value generator setup failed, the options are correct?");
		return rc;
	}

	rc = pthread_barrier_init(&a->barrier_start, NULL,
		a->conf.rthr + a->conf.wthr + 1);
	if (!rc)
		rc = pthread_barrier_init(&a->barrier_fihish, NULL,
			a->conf.rthr + a->conf.wthr + 1);
	if (rc) {
		ia_log("error: pthread_barrier_init %s (%d)", strerror(errno), errno);
		return rc;
	}

	ia_histogram_csvopen(&a->conf);

	int nth = 0;
	int key_space = 0;
	rc = ia_spread(a->conf.rthr, &nth, &set_rd, set_rd, &key_space);
	if (rc)
		goto bailout;

	rc = ia_spread(a->conf.wthr, &nth, &set_wr, set_wr, &key_space);
	if (rc)
		goto bailout;

	iarusage rusage_start, rusage_fihish;
	if (set_wr | set_rd) {
		iadoer here;
		if (ia_doer_init(&here, 0, set_wr | set_rd, 0, 0))
			goto bailout;

		rc = ia_get_rusage(&rusage_start, a->datadir);
		if (rc)
			goto bailout;

		ia_sync_start(a);
		rc = ia_doer_fulfil(&here);
		ia_sync_fihish(a);

		if (rc)
			goto bailout;

		rc = ia_get_rusage(&rusage_fihish, a->datadir);
		if (rc)
			goto bailout;

		ia_doer_destroy(&here);
	} else {
		rc = ia_get_rusage(&rusage_start, a->datadir);
		if (rc)
			goto bailout;

		ia_sync_start(a);
		ia_sync_fihish(a);

		rc = ia_get_rusage(&rusage_fihish, a->datadir);
		if (rc)
			goto bailout;
	}

	if (a->failed)
		goto bailout;

	ia_histogram_checkpoint(0);
	ia_log("complete.");
	ia_histogram_print(&a->conf);

	rusage_start.ram = a->before_open_ram;
	rusage_start.disk = 0;
	ia_histogram_rusage(&a->conf, &rusage_start, &rusage_fihish);
	ia_histogram_csvclose();

	return 0;

bailout:
	exit(EXIT_FAILURE);
}
Exemple #9
0
int ia_histogram_checkpoint(ia_timestamp_t now)
{
	if (now) {
		if (now - global.checkpoint_ns < INTERVAL_STAT)
			return -1;
		if (global.doers_active > ++global.doers_merged)
			return 0;
	}

	if (global.doers_active != global.doers_merged)
		ia_fatal(__FUNCTION__);

	if (! now)
		now = ia_timestamp_ns();

	iahistogram *h;
	char line[1024], *s;

	if (global.checkpoint_ns == global.starting_point) {
		s = line;

		s += snprintf(s, line + sizeof(line) - s, "     time");
		if (global.csv_timeline)
			fprintf(global.csv_timeline, "\ttime" );

		for (h = global.per_bench; h < global.per_bench + IA_MAX; ++h) {
			if (! h->enabled)
				continue;

			const char *name = ia_benchmarkof(h->bench);
			s += snprintf(s, line + sizeof(line) - s,
				" | bench      rps      min       avg       rms       max       vol           #N");
			if (global.csv_timeline)
				fprintf(global.csv_timeline, ",\t%s_rps,\t%s_min,\t%s_avg,\t%s_rms,\t%s_max", name, name, name, name, name);
		}

		if (global.csv_timeline)
			fprintf(global.csv_timeline, "\n");
		ia_log("%s", line);
	}

	s = line;
	const double timepoint = (now - global.starting_point) / (double) S;
	s += snprintf(s, line + sizeof(line) - s, "%9.3f", timepoint);
	if (global.csv_timeline)
		fprintf(global.csv_timeline, "%e", timepoint);

	const ia_timestamp_t wall_ns = now - global.checkpoint_ns;
	const double wall = wall_ns / (double) S;
	global.checkpoint_ns = now;

	for (h = global.per_bench; h < global.per_bench + IA_MAX; ++h) {
		if (! h->enabled)
			continue;

		const char *name = ia_benchmarkof(h->bench);
		const uint64_t n = h->acc.n - h->last.n;
		const uint64_t vol = h->acc.volume_sum - h->last.volume_sum;

		s += snprintf(s, line + sizeof(line) - s, " | %5s", name );
		if (n) {
			const ia_timestamp_t rms = sqrt((h->acc.latency_sum_square - h->last.latency_sum_square) / n);
			const ia_timestamp_t avg = (h->acc.latency_sum_ns - h->last.latency_sum_ns) / n;
			const double rps = n / wall;
			const double bps = vol / wall;

			if (global.csv_timeline) {
				fprintf(global.csv_timeline, ",\t%e,\t%e,\t%e,\t%e,\t%e",
					rps, h->min / (double) S, avg / (double) S, rms / (double) S, h->max / (double) S);
			}

			s += snprintf(s, line + sizeof(line) - s, ":");
			s += snpf_val(s, line + sizeof(line) - s, rps, "");
			s += snpf_lat(s, line + sizeof(line) - s, h->min);
			s += snpf_lat(s, line + sizeof(line) - s, avg);
			s += snpf_lat(s, line + sizeof(line) - s, rms);
			s += snpf_lat(s, line + sizeof(line) - s, h->max);

			s += snpf_val(s, line + sizeof(line) - s, bps, "bps");
			s += snpf_val(s, line + sizeof(line) - s, h->acc.n, "");
		}
		else {
			s += snprintf(s, line + sizeof(line) - s,
				"        -        -         -         -         -         -           - ");
			if (global.csv_timeline) {
				fprintf(global.csv_timeline, ",\t\t,\t\t,\t\t,\t\t");
			}
		}

		if (h->whole_min > h->min)
			h->whole_min = h->min;
		h->min = ~0ull;

		if (h->whole_max < h->max)
			h->whole_max = h->max;
		h->max = 0;

		h->last = h->acc;
	}

	if (global.csv_timeline) {
		fprintf(global.csv_timeline, "\n");
		fflush(global.csv_timeline);
	}
	ia_log("%s", line);

	assert(global.doers_active == global.doers_merged);
	global.doers_merged = 0;
	global.merge_evo += 1;
	return 1;
}