mirror of
https://github.com/torvalds/linux.git
synced 2026-05-13 00:28:54 +02:00
perf bench mem: Move mem op parameters into a structure
Move benchmark function parameters in struct bench_params. Reviewed-by: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Ankur Arora <ankur.a.arora@oracle.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Andy Lutomirski <luto@kernel.org> Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Dave Hansen <dave.hansen@linux.intel.com> Cc: David Hildenbrand <david@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com> Cc: Mateusz Guzik <mjguzik@gmail.com> Cc: Matthew Wilcox <willy@infradead.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Raghavendra K T <raghavendra.kt@amd.com> Cc: Thomas Gleixner <tglx@linutronix.de> Link: https://lore.kernel.org/r/20250917152418.4077386-4-ankur.a.arora@oracle.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
07e257245d
commit
dbf5dad154
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
static const char *size_str = "1MB";
|
||||
static const char *function_str = "all";
|
||||
static int nr_loops = 1;
|
||||
static unsigned int nr_loops = 1;
|
||||
static bool use_cycles;
|
||||
static int cycles_fd;
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ static const struct option options[] = {
|
|||
OPT_STRING('f', "function", &function_str, "all",
|
||||
"Specify the function to run, \"all\" runs all available functions, \"help\" lists them"),
|
||||
|
||||
OPT_INTEGER('l', "nr_loops", &nr_loops,
|
||||
OPT_UINTEGER('l', "nr_loops", &nr_loops,
|
||||
"Specify the number of loops to run. (default: 1)"),
|
||||
|
||||
OPT_BOOLEAN('c', "cycles", &use_cycles,
|
||||
|
|
@ -56,6 +56,12 @@ union bench_clock {
|
|||
struct timeval tv;
|
||||
};
|
||||
|
||||
struct bench_params {
|
||||
size_t size;
|
||||
size_t size_total;
|
||||
unsigned int nr_loops;
|
||||
};
|
||||
|
||||
typedef void *(*memcpy_t)(void *, const void *, size_t);
|
||||
typedef void *(*memset_t)(void *, int, size_t);
|
||||
|
||||
|
|
@ -134,17 +140,19 @@ static double timeval2double(struct timeval *ts)
|
|||
|
||||
struct bench_mem_info {
|
||||
const struct function *functions;
|
||||
union bench_clock (*do_op)(const struct function *r, size_t size, void *src, void *dst);
|
||||
union bench_clock (*do_op)(const struct function *r, struct bench_params *p,
|
||||
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, size_t size_total)
|
||||
static void __bench_mem_function(struct bench_mem_info *info, struct bench_params *p,
|
||||
int r_idx)
|
||||
{
|
||||
const struct function *r = &info->functions[r_idx];
|
||||
double result_bps = 0.0;
|
||||
union bench_clock rt = { 0 };
|
||||
void *src = NULL, *dst = zalloc(size);
|
||||
void *src = NULL, *dst = zalloc(p->size);
|
||||
|
||||
printf("# function '%s' (%s)\n", r->name, r->desc);
|
||||
|
||||
|
|
@ -152,7 +160,7 @@ static void __bench_mem_function(struct bench_mem_info *info, int r_idx, size_t
|
|||
goto out_alloc_failed;
|
||||
|
||||
if (info->alloc_src) {
|
||||
src = zalloc(size);
|
||||
src = zalloc(p->size);
|
||||
if (src == NULL)
|
||||
goto out_alloc_failed;
|
||||
}
|
||||
|
|
@ -160,23 +168,23 @@ static void __bench_mem_function(struct bench_mem_info *info, int r_idx, size_t
|
|||
if (bench_format == BENCH_FORMAT_DEFAULT)
|
||||
printf("# Copying %s bytes ...\n\n", size_str);
|
||||
|
||||
rt = info->do_op(r, size, src, dst);
|
||||
rt = info->do_op(r, p, src, dst);
|
||||
|
||||
switch (bench_format) {
|
||||
case BENCH_FORMAT_DEFAULT:
|
||||
if (use_cycles) {
|
||||
printf(" %14lf cycles/byte\n", (double)rt.cycles/(double)size_total);
|
||||
printf(" %14lf cycles/byte\n", (double)rt.cycles/(double)p->size_total);
|
||||
} else {
|
||||
result_bps = (double)size_total/timeval2double(&rt.tv);
|
||||
result_bps = (double)p->size_total/timeval2double(&rt.tv);
|
||||
print_bps(result_bps);
|
||||
}
|
||||
break;
|
||||
|
||||
case BENCH_FORMAT_SIMPLE:
|
||||
if (use_cycles) {
|
||||
printf("%lf\n", (double)rt.cycles/(double)size_total);
|
||||
printf("%lf\n", (double)rt.cycles/(double)p->size_total);
|
||||
} else {
|
||||
result_bps = (double)size_total/timeval2double(&rt.tv);
|
||||
result_bps = (double)p->size_total/timeval2double(&rt.tv);
|
||||
printf("%lf\n", result_bps);
|
||||
}
|
||||
break;
|
||||
|
|
@ -198,8 +206,7 @@ static void __bench_mem_function(struct bench_mem_info *info, int r_idx, size_t
|
|||
static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *info)
|
||||
{
|
||||
int i;
|
||||
size_t size;
|
||||
size_t size_total;
|
||||
struct bench_params p = { 0 };
|
||||
|
||||
argc = parse_options(argc, argv, options, info->usage, 0);
|
||||
|
||||
|
|
@ -211,17 +218,18 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *
|
|||
}
|
||||
}
|
||||
|
||||
size = (size_t)perf_atoll((char *)size_str);
|
||||
size_total = size * nr_loops;
|
||||
p.nr_loops = nr_loops;
|
||||
p.size = (size_t)perf_atoll((char *)size_str);
|
||||
|
||||
if ((s64)size <= 0) {
|
||||
if ((s64)p.size <= 0) {
|
||||
fprintf(stderr, "Invalid size:%s\n", size_str);
|
||||
return 1;
|
||||
}
|
||||
p.size_total = p.size * p.nr_loops;
|
||||
|
||||
if (!strncmp(function_str, "all", 3)) {
|
||||
for (i = 0; info->functions[i].name; i++)
|
||||
__bench_mem_function(info, i, size, size_total);
|
||||
__bench_mem_function(info, &p, i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -240,7 +248,7 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *
|
|||
return 1;
|
||||
}
|
||||
|
||||
__bench_mem_function(info, i, size, size_total);
|
||||
__bench_mem_function(info, &p, i);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -257,18 +265,17 @@ static void memcpy_prefault(memcpy_t fn, size_t size, void *src, void *dst)
|
|||
fn(dst, src, size);
|
||||
}
|
||||
|
||||
static union bench_clock do_memcpy(const struct function *r, size_t size,
|
||||
static union bench_clock do_memcpy(const struct function *r, struct bench_params *p,
|
||||
void *src, void *dst)
|
||||
{
|
||||
union bench_clock start, end;
|
||||
memcpy_t fn = r->fn.memcpy;
|
||||
int i;
|
||||
|
||||
memcpy_prefault(fn, size, src, dst);
|
||||
memcpy_prefault(fn, p->size, src, dst);
|
||||
|
||||
clock_get(&start);
|
||||
for (i = 0; i < nr_loops; ++i)
|
||||
fn(dst, src, size);
|
||||
for (unsigned int i = 0; i < p->nr_loops; ++i)
|
||||
fn(dst, src, p->size);
|
||||
clock_get(&end);
|
||||
|
||||
return clock_diff(&start, &end);
|
||||
|
|
@ -305,22 +312,21 @@ int bench_mem_memcpy(int argc, const char **argv)
|
|||
return bench_mem_common(argc, argv, &info);
|
||||
}
|
||||
|
||||
static union bench_clock do_memset(const struct function *r, size_t size,
|
||||
static union bench_clock do_memset(const struct function *r, struct bench_params *p,
|
||||
void *src __maybe_unused, void *dst)
|
||||
{
|
||||
union bench_clock start, end;
|
||||
memset_t fn = r->fn.memset;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* We prefault the freshly allocated memory range here,
|
||||
* to not measure page fault overhead:
|
||||
*/
|
||||
fn(dst, -1, size);
|
||||
fn(dst, -1, p->size);
|
||||
|
||||
clock_get(&start);
|
||||
for (i = 0; i < nr_loops; ++i)
|
||||
fn(dst, i, size);
|
||||
for (unsigned int i = 0; i < p->nr_loops; ++i)
|
||||
fn(dst, i, p->size);
|
||||
clock_get(&end);
|
||||
|
||||
return clock_diff(&start, &end);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user