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 {
|
struct bench_mem_info {
|
||||||
const struct function *functions;
|
const struct function *functions;
|
||||||
u64 (*do_cycles)(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);
|
double (*do_gettimeofday)(const struct function *r, size_t size, void *src, void *dst);
|
||||||
const char *const *usage;
|
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)
|
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];
|
const struct function *r = &info->functions[r_idx];
|
||||||
double result_bps = 0.0;
|
double result_bps = 0.0;
|
||||||
u64 result_cycles = 0;
|
u64 result_cycles = 0;
|
||||||
|
void *src = NULL, *dst = zalloc(size);
|
||||||
|
|
||||||
printf("# function '%s' (%s)\n", r->name, r->desc);
|
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)
|
if (bench_format == BENCH_FORMAT_DEFAULT)
|
||||||
printf("# Copying %s bytes ...\n\n", size_str);
|
printf("# Copying %s bytes ...\n\n", size_str);
|
||||||
|
|
||||||
if (use_cycles) {
|
if (use_cycles) {
|
||||||
result_cycles = info->do_cycles(r, size);
|
result_cycles = info->do_cycles(r, size, src, dst);
|
||||||
} else {
|
} else {
|
||||||
result_bps = info->do_gettimeofday(r, size);
|
result_bps = info->do_gettimeofday(r, size, src, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (bench_format) {
|
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);
|
BUG_ON(1);
|
||||||
break;
|
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)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void memcpy_alloc_mem(void **dst, void **src, size_t size)
|
static u64 do_memcpy_cycles(const struct function *r, size_t size, void *src, void *dst)
|
||||||
{
|
|
||||||
*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)
|
|
||||||
{
|
{
|
||||||
u64 cycle_start = 0ULL, cycle_end = 0ULL;
|
u64 cycle_start = 0ULL, cycle_end = 0ULL;
|
||||||
void *src = NULL, *dst = NULL;
|
|
||||||
memcpy_t fn = r->fn.memcpy;
|
memcpy_t fn = r->fn.memcpy;
|
||||||
int i;
|
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,
|
* 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);
|
fn(dst, src, size);
|
||||||
cycle_end = get_cycles();
|
cycle_end = get_cycles();
|
||||||
|
|
||||||
free(src);
|
|
||||||
free(dst);
|
|
||||||
return cycle_end - cycle_start;
|
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;
|
struct timeval tv_start, tv_end, tv_diff;
|
||||||
memcpy_t fn = r->fn.memcpy;
|
memcpy_t fn = r->fn.memcpy;
|
||||||
void *src = NULL, *dst = NULL;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
memcpy_alloc_mem(&dst, &src, size);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We prefault the freshly allocated memory range here,
|
* We prefault the freshly allocated memory range here,
|
||||||
* to not measure page fault overhead:
|
* 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);
|
timersub(&tv_end, &tv_start, &tv_diff);
|
||||||
|
|
||||||
free(src);
|
|
||||||
free(dst);
|
|
||||||
|
|
||||||
return (double)(((double)size * nr_loops) / timeval2double(&tv_diff));
|
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_cycles = do_memcpy_cycles,
|
||||||
.do_gettimeofday = do_memcpy_gettimeofday,
|
.do_gettimeofday = do_memcpy_gettimeofday,
|
||||||
.usage = bench_mem_memcpy_usage,
|
.usage = bench_mem_memcpy_usage,
|
||||||
|
.alloc_src = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
return bench_mem_common(argc, argv, &info);
|
return bench_mem_common(argc, argv, &info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void memset_alloc_mem(void **dst, size_t size)
|
static u64 do_memset_cycles(const struct function *r, size_t size, void *src __maybe_unused, void *dst)
|
||||||
{
|
|
||||||
*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)
|
|
||||||
{
|
{
|
||||||
u64 cycle_start = 0ULL, cycle_end = 0ULL;
|
u64 cycle_start = 0ULL, cycle_end = 0ULL;
|
||||||
memset_t fn = r->fn.memset;
|
memset_t fn = r->fn.memset;
|
||||||
void *dst = NULL;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
memset_alloc_mem(&dst, size);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We prefault the freshly allocated memory range here,
|
* We prefault the freshly allocated memory range here,
|
||||||
* to not measure page fault overhead:
|
* 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);
|
fn(dst, i, size);
|
||||||
cycle_end = get_cycles();
|
cycle_end = get_cycles();
|
||||||
|
|
||||||
free(dst);
|
|
||||||
return cycle_end - cycle_start;
|
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;
|
struct timeval tv_start, tv_end, tv_diff;
|
||||||
memset_t fn = r->fn.memset;
|
memset_t fn = r->fn.memset;
|
||||||
void *dst = NULL;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
memset_alloc_mem(&dst, size);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We prefault the freshly allocated memory range here,
|
* We prefault the freshly allocated memory range here,
|
||||||
* to not measure page fault overhead:
|
* 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);
|
timersub(&tv_end, &tv_start, &tv_diff);
|
||||||
|
|
||||||
free(dst);
|
|
||||||
return (double)(((double)size * nr_loops) / timeval2double(&tv_diff));
|
return (double)(((double)size * nr_loops) / timeval2double(&tv_diff));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user