Skip to content

Commit

Permalink
pmembench: add pmemobj_persist benchmak
Browse files Browse the repository at this point in the history
  • Loading branch information
Jan M Michalski committed Oct 20, 2016
1 parent b236af6 commit a9b8323
Show file tree
Hide file tree
Showing 3 changed files with 325 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/benchmarks/Makefile
Expand Up @@ -73,6 +73,7 @@ SRC=pmembench.c\
pmem_memcpy.c\
pmem_flush.c\
pmemobj_gen.c\
pmemobj_persist.c\
obj_pmalloc.c\
obj_locks.c\
obj_lanes.c\
Expand All @@ -93,6 +94,7 @@ CONFIGS=pmembench_log\
pmembench_memcpy\
pmembench_flush\
pmembench_obj_pmalloc\
pmembench_obj_persist\
pmembench_obj_gen\
pmembench_obj_locks\
pmembench_obj_lanes\
Expand Down
25 changes: 25 additions & 0 deletions src/benchmarks/pmembench_obj_persist.cfg
@@ -0,0 +1,25 @@
#
# pmembench_obj_persist.cfg -- this is an example config file for pmembench
# with scenarios for pmemobj_persist() benchmark
#

# Global parameters
[global]
group = obj_persist
file = testfile.obj_persist
ops-per-thread = 10000

[pmemobj_persist_DS8]
bench = pmemobj_persist
threads = 1:+1:32
data-size = 8

[pmemobj_persist_DS512]
bench = pmemobj_persist
threads = 1:+1:32
data-size = 512

[pmemobj_persist_DS1024]
bench = pmemobj_persist
threads = 1:+1:32
data-size = 1024
298 changes: 298 additions & 0 deletions src/benchmarks/pmemobj_persist.c
@@ -0,0 +1,298 @@
/*
* Copyright 2016, Intel Corporation
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* * Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/*
* pmemobj_persist.c -- pmemobj persist benchmarks definition
*/

#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <stddef.h>
#include <sys/mman.h>
#include <sys/file.h>

#include "libpmemobj.h"
#include "benchmark.h"

/*
* The factor used for PMEM pool size calculation, accounts for metadata,
* fragmentation and etc.
*/
#define FACTOR 3

/* The minimum allocation size that pmalloc can perform */
#define ALLOC_MIN_SIZE 64

/* OOB and allocation header size */
#define OOB_HEADER_SIZE 64

#define CONST_B 0xFF

/*
* prog_args -- benchmark specific command line options
*/
struct prog_args {
size_t minsize; /* minimum size for random allocation size */
bool use_random_size; /* if set, use random size allocations */
bool no_warmup; /* do not do warmup */
unsigned seed; /* seed for random numbers */
};

/*
* obj_bench -- benchmark context
*/
struct obj_bench {
PMEMobjpool *pop; /* persistent pool handle */
struct prog_args *pa; /* prog_args structure */
PMEMoid *oids; /* vector of allocated objects */
void **ptrs; /* pointers to allocated objects */
uint64_t nobjs; /* number of allocated objects */
size_t obj_size; /* size of each allocated objects */
int const_b; /* memset() value */
};

static struct benchmark_clo obj_persist_clo[] = {
{
.opt_short = 'w',
.opt_long = "no-warmup",
.descr = "Don't do warmup",
.def = false,
.type = CLO_TYPE_FLAG,
.off = clo_field_offset(struct prog_args, no_warmup),
},
};

/*
* init_objects -- allocate persistent objects and obtain direct pointers
*/
static int
init_objects(struct obj_bench *ob)
{
ob->oids = malloc(ob->nobjs * sizeof(*ob->oids));
if (!ob->oids) {
perror("malloc");
return -1;
}

ob->ptrs = malloc(ob->nobjs * sizeof(*ob->ptrs));
if (!ob->ptrs) {
perror("malloc");
goto err_malloc;
}

for (uint64_t i = 0; i < ob->nobjs; i++) {
PMEMoid oid;
void *ptr;
if (pmemobj_alloc(ob->pop, &oid, ob->obj_size, 0, NULL, NULL)) {
perror("pmemobj_alloc");
goto err_palloc;
}
ptr = pmemobj_direct(oid);
if (!ptr) {
perror("pmemobj_direct");
goto err_palloc;
}
ob->oids[i] = oid;
ob->ptrs[i] = ptr;
}

return 0;

err_palloc:
free(ob->ptrs);
err_malloc:
free(ob->oids);
return -1;
}

/*
* do_warmup -- does the warmup by writing the whole pool area
*/
static int
do_warmup(struct obj_bench *ob)
{
for (uint64_t i = 0; i < ob->nobjs; ++i) {
memset(ob->ptrs[i], 0, ob->obj_size);
pmemobj_persist(ob->pop, ob->ptrs[i], ob->obj_size);
}

return 0;
}

/*
* obj_persist_op -- actual benchmark operation
*/
static int
obj_persist_op(struct benchmark *bench, struct operation_info *info)
{
struct obj_bench *ob = (struct obj_bench *)pmembench_get_priv(bench);
uint64_t idx = info->worker->index * info->args->n_ops_per_thread
+ info->index;

assert(idx < ob->nobjs);

void *ptr = ob->ptrs[idx];
memset(ptr, ob->const_b, ob->obj_size);
pmemobj_persist(ob->pop, ptr, ob->obj_size);

return 0;
}

/*
* obj_persist_init -- initialization function
*/
static int
obj_persist_init(struct benchmark *bench, struct benchmark_args *args)
{
assert(bench != NULL);
assert(args != NULL);
assert(args->opts != NULL);

struct prog_args *pa = (struct prog_args *)args->opts;
size_t poolsize;
if (pa->minsize >= args->dsize) {
fprintf(stderr, "Wrong params - allocation size\n");
return -1;
}

struct obj_bench *ob = malloc(sizeof(struct obj_bench));
if (ob == NULL) {
perror("malloc");
return -1;
}
pmembench_set_priv(bench, ob);

ob->pa = pa;

/* initialize memset() value */
ob->const_b = CONST_B;

ob->nobjs = args->n_ops_per_thread * args->n_threads;

/* Create pmemobj pool. */
ob->obj_size = args->dsize;
if (ob->obj_size < ALLOC_MIN_SIZE)
ob->obj_size = ALLOC_MIN_SIZE;

/* For data objects */
poolsize = ob->nobjs * (ob->obj_size + OOB_HEADER_SIZE);

/* multiply by FACTOR for metadata, fragmentation, etc. */
poolsize = poolsize * FACTOR;

if (args->is_poolset) {
if (args->fsize < poolsize) {
fprintf(stderr, "insufficient size of poolset\n");
goto free_ob;
}
poolsize = 0;
} else {
if (poolsize < PMEMOBJ_MIN_POOL)
poolsize = PMEMOBJ_MIN_POOL;

}

ob->pop = pmemobj_create(args->fname, NULL, poolsize, args->fmode);
if (ob->pop == NULL) {
fprintf(stderr, "%s\n", pmemobj_errormsg());
goto free_ob;
}

if (init_objects(ob)) {
goto free_pop;
}

if (!ob->pa->no_warmup) {
if (do_warmup(ob)) {
fprintf(stderr, "do_warmup() function failed.");
goto free_objs;
}
}

return 0;

free_objs:
for (uint64_t i = 0; i < ob->nobjs; ++i) {
pmemobj_free(&ob->oids[i]);
}
free(ob->oids);
free(ob->ptrs);
free_pop:
pmemobj_close(ob->pop);
free_ob:
free(ob);
return -1;
}

/*
* obj_persist_exit -- benchmark cleanup function
*/
static int
obj_persist_exit(struct benchmark *bench, struct benchmark_args *args)
{
struct obj_bench *ob = pmembench_get_priv(bench);

for (uint64_t i = 0; i < ob->nobjs; ++i) {
pmemobj_free(&ob->oids[i]);
}

pmemobj_close(ob->pop);

free(ob->oids);
free(ob->ptrs);
free(ob);
return 0;
}

/* Stores information about benchmark. */
static struct benchmark_info obj_persist_info = {
.name = "pmemobj_persist",
.brief = "Benchmark for pmemobj_persist() operation",
.init = obj_persist_init,
.exit = obj_persist_exit,
.multithread = true,
.multiops = true,
.operation = obj_persist_op,
.measure_time = true,
.clos = obj_persist_clo,
.nclos = ARRAY_SIZE(obj_persist_clo),
.opts_size = sizeof(struct prog_args),
.rm_file = true,
.allow_poolset = true,
};

REGISTER_BENCHMARK(obj_persist_info);

0 comments on commit a9b8323

Please sign in to comment.