aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/bench/mem-memcpy.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/bench/mem-memcpy.c')
-rw-r--r--tools/perf/bench/mem-memcpy.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/tools/perf/bench/mem-memcpy.c b/tools/perf/bench/mem-memcpy.c
index 4a4493a7a1f8..e18be70c8a47 100644
--- a/tools/perf/bench/mem-memcpy.c
+++ b/tools/perf/bench/mem-memcpy.c
@@ -13,6 +13,7 @@
13#include "../util/cloexec.h" 13#include "../util/cloexec.h"
14#include "bench.h" 14#include "bench.h"
15#include "mem-memcpy-arch.h" 15#include "mem-memcpy-arch.h"
16#include "mem-memset-arch.h"
16 17
17#include <stdio.h> 18#include <stdio.h>
18#include <stdlib.h> 19#include <stdlib.h>
@@ -48,12 +49,14 @@ static const struct option options[] = {
48}; 49};
49 50
50typedef void *(*memcpy_t)(void *, const void *, size_t); 51typedef void *(*memcpy_t)(void *, const void *, size_t);
52typedef void *(*memset_t)(void *, int, size_t);
51 53
52struct routine { 54struct routine {
53 const char *name; 55 const char *name;
54 const char *desc; 56 const char *desc;
55 union { 57 union {
56 memcpy_t memcpy; 58 memcpy_t memcpy;
59 memset_t memset;
57 } fn; 60 } fn;
58}; 61};
59 62
@@ -336,3 +339,90 @@ int bench_mem_memcpy(int argc, const char **argv,
336 339
337 return bench_mem_common(argc, argv, prefix, &info); 340 return bench_mem_common(argc, argv, prefix, &info);
338} 341}
342
343static void memset_alloc_mem(void **dst, size_t length)
344{
345 *dst = zalloc(length);
346 if (!*dst)
347 die("memory allocation failed - maybe length is too large?\n");
348}
349
350static u64 do_memset_cycle(const struct routine *r, size_t len, bool prefault)
351{
352 u64 cycle_start = 0ULL, cycle_end = 0ULL;
353 memset_t fn = r->fn.memset;
354 void *dst = NULL;
355 int i;
356
357 memset_alloc_mem(&dst, len);
358
359 if (prefault)
360 fn(dst, -1, len);
361
362 cycle_start = get_cycle();
363 for (i = 0; i < iterations; ++i)
364 fn(dst, i, len);
365 cycle_end = get_cycle();
366
367 free(dst);
368 return cycle_end - cycle_start;
369}
370
371static double do_memset_gettimeofday(const struct routine *r, size_t len,
372 bool prefault)
373{
374 struct timeval tv_start, tv_end, tv_diff;
375 memset_t fn = r->fn.memset;
376 void *dst = NULL;
377 int i;
378
379 memset_alloc_mem(&dst, len);
380
381 if (prefault)
382 fn(dst, -1, len);
383
384 BUG_ON(gettimeofday(&tv_start, NULL));
385 for (i = 0; i < iterations; ++i)
386 fn(dst, i, len);
387 BUG_ON(gettimeofday(&tv_end, NULL));
388
389 timersub(&tv_end, &tv_start, &tv_diff);
390
391 free(dst);
392 return (double)((double)len / timeval2double(&tv_diff));
393}
394
395static const char * const bench_mem_memset_usage[] = {
396 "perf bench mem memset <options>",
397 NULL
398};
399
400static const struct routine memset_routines[] = {
401 { .name ="default",
402 .desc = "Default memset() provided by glibc",
403 .fn.memset = memset },
404#ifdef HAVE_ARCH_X86_64_SUPPORT
405
406#define MEMSET_FN(_fn, _name, _desc) { .name = _name, .desc = _desc, .fn.memset = _fn },
407#include "mem-memset-x86-64-asm-def.h"
408#undef MEMSET_FN
409
410#endif
411
412 { .name = NULL,
413 .desc = NULL,
414 .fn.memset = NULL }
415};
416
417int bench_mem_memset(int argc, const char **argv,
418 const char *prefix __maybe_unused)
419{
420 struct bench_mem_info info = {
421 .routines = memset_routines,
422 .do_cycle = do_memset_cycle,
423 .do_gettimeofday = do_memset_gettimeofday,
424 .usage = bench_mem_memset_usage,
425 };
426
427 return bench_mem_common(argc, argv, prefix, &info);
428}