perf bench mem: Move boilerplate memory allocation to the infrastructure
Instead of having all tests perform alloc/free, do it in the code that calls the do_cycles() and do_gettimeofday() functions. Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Wang Nan <wangnan0@huawei.com> Link: http://lkml.kernel.org/n/tip-lywj4mbdb1m9x1z9asivwuuy@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
e36b7821a9
commit
47b5757bac
@ -106,9 +106,10 @@ static double timeval2double(struct timeval *ts)
|
||||
|
||||
struct bench_mem_info {
|
||||
const struct function *functions;
|
||||
u64 (*do_cycles)(const struct function *r, size_t size);
|
||||
double (*do_gettimeofday)(const struct function *r, size_t size);
|
||||
u64 (*do_cycles)(const struct function *r, size_t size, void *src, void *dst);
|
||||
double (*do_gettimeofday)(const struct function *r, size_t size, void *src, void *dst);
|
||||
const char *const *usage;
|
||||
bool alloc_src;
|
||||
};
|
||||
|
||||
static void __bench_mem_function(struct bench_mem_info *info, int r_idx, size_t size, double size_total)
|
||||
@ -116,16 +117,26 @@ static void __bench_mem_function(struct bench_mem_info *info, int r_idx, size_t
|
||||
const struct function *r = &info->functions[r_idx];
|
||||
double result_bps = 0.0;
|
||||
u64 result_cycles = 0;
|
||||
void *src = NULL, *dst = zalloc(size);
|
||||
|
||||
printf("# function '%s' (%s)\n", r->name, r->desc);
|
||||
|
||||
if (dst == NULL)
|
||||
goto out_alloc_failed;
|
||||
|
||||
if (info->alloc_src) {
|
||||
src = zalloc(size);
|
||||
if (src == NULL)
|
||||
goto out_alloc_failed;
|
||||
}
|
||||
|
||||
if (bench_format == BENCH_FORMAT_DEFAULT)
|
||||
printf("# Copying %s bytes ...\n\n", size_str);
|
||||
|
||||
if (use_cycles) {
|
||||
result_cycles = info->do_cycles(r, size);
|
||||
result_cycles = info->do_cycles(r, size, src, dst);
|
||||
} else {
|
||||
result_bps = info->do_gettimeofday(r, size);
|
||||
result_bps = info->do_gettimeofday(r, size, src, dst);
|
||||
}
|
||||
|
||||
switch (bench_format) {
|
||||
@ -149,6 +160,14 @@ static void __bench_mem_function(struct bench_mem_info *info, int r_idx, size_t
|
||||
BUG_ON(1);
|
||||
break;
|
||||
}
|
||||
|
||||
out_free:
|
||||
free(src);
|
||||
free(dst);
|
||||
return;
|
||||
out_alloc_failed:
|
||||
printf("# Memory allocation failed - maybe size (%s) is too large?\n", size_str);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *info)
|
||||
@ -201,28 +220,14 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void memcpy_alloc_mem(void **dst, void **src, size_t size)
|
||||
{
|
||||
*dst = zalloc(size);
|
||||
if (!*dst)
|
||||
die("memory allocation failed - maybe size is too large?\n");
|
||||
|
||||
*src = zalloc(size);
|
||||
if (!*src)
|
||||
die("memory allocation failed - maybe size is too large?\n");
|
||||
|
||||
/* Make sure to always prefault zero pages even if MMAP_THRESH is crossed: */
|
||||
memset(*src, 0, size);
|
||||
}
|
||||
|
||||
static u64 do_memcpy_cycles(const struct function *r, size_t size)
|
||||
static u64 do_memcpy_cycles(const struct function *r, size_t size, void *src, void *dst)
|
||||
{
|
||||
u64 cycle_start = 0ULL, cycle_end = 0ULL;
|
||||
void *src = NULL, *dst = NULL;
|
||||
memcpy_t fn = r->fn.memcpy;
|
||||
int i;
|
||||
|
||||
memcpy_alloc_mem(&dst, &src, size);
|
||||
/* Make sure to always prefault zero pages even if MMAP_THRESH is crossed: */
|
||||
memset(src, 0, size);
|
||||
|
||||
/*
|
||||
* We prefault the freshly allocated memory range here,
|
||||
@ -235,20 +240,15 @@ static u64 do_memcpy_cycles(const struct function *r, size_t size)
|
||||
fn(dst, src, size);
|
||||
cycle_end = get_cycles();
|
||||
|
||||
free(src);
|
||||
free(dst);
|
||||
return cycle_end - cycle_start;
|
||||
}
|
||||
|
||||
static double do_memcpy_gettimeofday(const struct function *r, size_t size)
|
||||
static double do_memcpy_gettimeofday(const struct function *r, size_t size, void *src, void *dst)
|
||||
{
|
||||
struct timeval tv_start, tv_end, tv_diff;
|
||||
memcpy_t fn = r->fn.memcpy;
|
||||
void *src = NULL, *dst = NULL;
|
||||
int i;
|
||||
|
||||
memcpy_alloc_mem(&dst, &src, size);
|
||||
|
||||
/*
|
||||
* We prefault the freshly allocated memory range here,
|
||||
* to not measure page fault overhead:
|
||||
@ -262,9 +262,6 @@ static double do_memcpy_gettimeofday(const struct function *r, size_t size)
|
||||
|
||||
timersub(&tv_end, &tv_start, &tv_diff);
|
||||
|
||||
free(src);
|
||||
free(dst);
|
||||
|
||||
return (double)(((double)size * nr_loops) / timeval2double(&tv_diff));
|
||||
}
|
||||
|
||||
@ -294,27 +291,18 @@ int bench_mem_memcpy(int argc, const char **argv, const char *prefix __maybe_unu
|
||||
.do_cycles = do_memcpy_cycles,
|
||||
.do_gettimeofday = do_memcpy_gettimeofday,
|
||||
.usage = bench_mem_memcpy_usage,
|
||||
.alloc_src = true,
|
||||
};
|
||||
|
||||
return bench_mem_common(argc, argv, &info);
|
||||
}
|
||||
|
||||
static void memset_alloc_mem(void **dst, size_t size)
|
||||
{
|
||||
*dst = zalloc(size);
|
||||
if (!*dst)
|
||||
die("memory allocation failed - maybe size is too large?\n");
|
||||
}
|
||||
|
||||
static u64 do_memset_cycles(const struct function *r, size_t size)
|
||||
static u64 do_memset_cycles(const struct function *r, size_t size, void *src __maybe_unused, void *dst)
|
||||
{
|
||||
u64 cycle_start = 0ULL, cycle_end = 0ULL;
|
||||
memset_t fn = r->fn.memset;
|
||||
void *dst = NULL;
|
||||
int i;
|
||||
|
||||
memset_alloc_mem(&dst, size);
|
||||
|
||||
/*
|
||||
* We prefault the freshly allocated memory range here,
|
||||
* to not measure page fault overhead:
|
||||
@ -326,19 +314,15 @@ static u64 do_memset_cycles(const struct function *r, size_t size)
|
||||
fn(dst, i, size);
|
||||
cycle_end = get_cycles();
|
||||
|
||||
free(dst);
|
||||
return cycle_end - cycle_start;
|
||||
}
|
||||
|
||||
static double do_memset_gettimeofday(const struct function *r, size_t size)
|
||||
static double do_memset_gettimeofday(const struct function *r, size_t size, void *src __maybe_unused, void *dst)
|
||||
{
|
||||
struct timeval tv_start, tv_end, tv_diff;
|
||||
memset_t fn = r->fn.memset;
|
||||
void *dst = NULL;
|
||||
int i;
|
||||
|
||||
memset_alloc_mem(&dst, size);
|
||||
|
||||
/*
|
||||
* We prefault the freshly allocated memory range here,
|
||||
* to not measure page fault overhead:
|
||||
@ -352,7 +336,6 @@ static double do_memset_gettimeofday(const struct function *r, size_t size)
|
||||
|
||||
timersub(&tv_end, &tv_start, &tv_diff);
|
||||
|
||||
free(dst);
|
||||
return (double)(((double)size * nr_loops) / timeval2double(&tv_diff));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user