Skip to content

Commit 79a0194

Browse files
terminusacmel
authored andcommitted
perf bench mem: Remove repetition around time measurement
We have two copies of each mem benchmark: one using cycles to measure time, the second for gettimeofday(). Unify. 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> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
1 parent b0f4ade commit 79a0194

File tree

1 file changed

+46
-64
lines changed

1 file changed

+46
-64
lines changed

tools/perf/bench/mem-functions.c

Lines changed: 46 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ static const struct option options[] = {
5151
OPT_END()
5252
};
5353

54+
union bench_clock {
55+
u64 cycles;
56+
struct timeval tv;
57+
};
58+
5459
typedef void *(*memcpy_t)(void *, const void *, size_t);
5560
typedef void *(*memset_t)(void *, int, size_t);
5661

@@ -91,6 +96,26 @@ static u64 get_cycles(void)
9196
return clk;
9297
}
9398

99+
static void clock_get(union bench_clock *t)
100+
{
101+
if (use_cycles)
102+
t->cycles = get_cycles();
103+
else
104+
BUG_ON(gettimeofday(&t->tv, NULL));
105+
}
106+
107+
static union bench_clock clock_diff(union bench_clock *s, union bench_clock *e)
108+
{
109+
union bench_clock t;
110+
111+
if (use_cycles)
112+
t.cycles = e->cycles - s->cycles;
113+
else
114+
timersub(&e->tv, &s->tv, &t.tv);
115+
116+
return t;
117+
}
118+
94119
static double timeval2double(struct timeval *ts)
95120
{
96121
return (double)ts->tv_sec + (double)ts->tv_usec / (double)USEC_PER_SEC;
@@ -109,8 +134,7 @@ static double timeval2double(struct timeval *ts)
109134

110135
struct bench_mem_info {
111136
const struct function *functions;
112-
u64 (*do_cycles)(const struct function *r, size_t size, void *src, void *dst);
113-
double (*do_gettimeofday)(const struct function *r, size_t size, void *src, void *dst);
137+
union bench_clock (*do_op)(const struct function *r, size_t size, void *src, void *dst);
114138
const char *const *usage;
115139
bool alloc_src;
116140
};
@@ -119,7 +143,7 @@ static void __bench_mem_function(struct bench_mem_info *info, int r_idx, size_t
119143
{
120144
const struct function *r = &info->functions[r_idx];
121145
double result_bps = 0.0;
122-
u64 result_cycles = 0;
146+
union bench_clock rt = { 0 };
123147
void *src = NULL, *dst = zalloc(size);
124148

125149
printf("# function '%s' (%s)\n", r->name, r->desc);
@@ -136,25 +160,23 @@ static void __bench_mem_function(struct bench_mem_info *info, int r_idx, size_t
136160
if (bench_format == BENCH_FORMAT_DEFAULT)
137161
printf("# Copying %s bytes ...\n\n", size_str);
138162

139-
if (use_cycles) {
140-
result_cycles = info->do_cycles(r, size, src, dst);
141-
} else {
142-
result_bps = info->do_gettimeofday(r, size, src, dst);
143-
}
163+
rt = info->do_op(r, size, src, dst);
144164

145165
switch (bench_format) {
146166
case BENCH_FORMAT_DEFAULT:
147167
if (use_cycles) {
148-
printf(" %14lf cycles/byte\n", (double)result_cycles/size_total);
168+
printf(" %14lf cycles/byte\n", (double)rt.cycles/size_total);
149169
} else {
170+
result_bps = size_total/timeval2double(&rt.tv);
150171
print_bps(result_bps);
151172
}
152173
break;
153174

154175
case BENCH_FORMAT_SIMPLE:
155176
if (use_cycles) {
156-
printf("%lf\n", (double)result_cycles/size_total);
177+
printf("%lf\n", (double)rt.cycles/size_total);
157178
} else {
179+
result_bps = size_total/timeval2double(&rt.tv);
158180
printf("%lf\n", result_bps);
159181
}
160182
break;
@@ -235,38 +257,21 @@ static void memcpy_prefault(memcpy_t fn, size_t size, void *src, void *dst)
235257
fn(dst, src, size);
236258
}
237259

238-
static u64 do_memcpy_cycles(const struct function *r, size_t size, void *src, void *dst)
239-
{
240-
u64 cycle_start = 0ULL, cycle_end = 0ULL;
241-
memcpy_t fn = r->fn.memcpy;
242-
int i;
243-
244-
memcpy_prefault(fn, size, src, dst);
245-
246-
cycle_start = get_cycles();
247-
for (i = 0; i < nr_loops; ++i)
248-
fn(dst, src, size);
249-
cycle_end = get_cycles();
250-
251-
return cycle_end - cycle_start;
252-
}
253-
254-
static double do_memcpy_gettimeofday(const struct function *r, size_t size, void *src, void *dst)
260+
static union bench_clock do_memcpy(const struct function *r, size_t size,
261+
void *src, void *dst)
255262
{
256-
struct timeval tv_start, tv_end, tv_diff;
263+
union bench_clock start, end;
257264
memcpy_t fn = r->fn.memcpy;
258265
int i;
259266

260267
memcpy_prefault(fn, size, src, dst);
261268

262-
BUG_ON(gettimeofday(&tv_start, NULL));
269+
clock_get(&start);
263270
for (i = 0; i < nr_loops; ++i)
264271
fn(dst, src, size);
265-
BUG_ON(gettimeofday(&tv_end, NULL));
272+
clock_get(&end);
266273

267-
timersub(&tv_end, &tv_start, &tv_diff);
268-
269-
return (double)(((double)size * nr_loops) / timeval2double(&tv_diff));
274+
return clock_diff(&start, &end);
270275
}
271276

272277
struct function memcpy_functions[] = {
@@ -292,38 +297,18 @@ int bench_mem_memcpy(int argc, const char **argv)
292297
{
293298
struct bench_mem_info info = {
294299
.functions = memcpy_functions,
295-
.do_cycles = do_memcpy_cycles,
296-
.do_gettimeofday = do_memcpy_gettimeofday,
300+
.do_op = do_memcpy,
297301
.usage = bench_mem_memcpy_usage,
298302
.alloc_src = true,
299303
};
300304

301305
return bench_mem_common(argc, argv, &info);
302306
}
303307

304-
static u64 do_memset_cycles(const struct function *r, size_t size, void *src __maybe_unused, void *dst)
305-
{
306-
u64 cycle_start = 0ULL, cycle_end = 0ULL;
307-
memset_t fn = r->fn.memset;
308-
int i;
309-
310-
/*
311-
* We prefault the freshly allocated memory range here,
312-
* to not measure page fault overhead:
313-
*/
314-
fn(dst, -1, size);
315-
316-
cycle_start = get_cycles();
317-
for (i = 0; i < nr_loops; ++i)
318-
fn(dst, i, size);
319-
cycle_end = get_cycles();
320-
321-
return cycle_end - cycle_start;
322-
}
323-
324-
static double do_memset_gettimeofday(const struct function *r, size_t size, void *src __maybe_unused, void *dst)
308+
static union bench_clock do_memset(const struct function *r, size_t size,
309+
void *src __maybe_unused, void *dst)
325310
{
326-
struct timeval tv_start, tv_end, tv_diff;
311+
union bench_clock start, end;
327312
memset_t fn = r->fn.memset;
328313
int i;
329314

@@ -333,14 +318,12 @@ static double do_memset_gettimeofday(const struct function *r, size_t size, void
333318
*/
334319
fn(dst, -1, size);
335320

336-
BUG_ON(gettimeofday(&tv_start, NULL));
321+
clock_get(&start);
337322
for (i = 0; i < nr_loops; ++i)
338323
fn(dst, i, size);
339-
BUG_ON(gettimeofday(&tv_end, NULL));
340-
341-
timersub(&tv_end, &tv_start, &tv_diff);
324+
clock_get(&end);
342325

343-
return (double)(((double)size * nr_loops) / timeval2double(&tv_diff));
326+
return clock_diff(&start, &end);
344327
}
345328

346329
static const char * const bench_mem_memset_usage[] = {
@@ -366,8 +349,7 @@ int bench_mem_memset(int argc, const char **argv)
366349
{
367350
struct bench_mem_info info = {
368351
.functions = memset_functions,
369-
.do_cycles = do_memset_cycles,
370-
.do_gettimeofday = do_memset_gettimeofday,
352+
.do_op = do_memset,
371353
.usage = bench_mem_memset_usage,
372354
};
373355

0 commit comments

Comments
 (0)