1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
29b2fa7f3SIngo Molnar /*
39b2fa7f3SIngo Molnar * mem-memcpy.c
49b2fa7f3SIngo Molnar *
59b2fa7f3SIngo Molnar * Simple memcpy() and memset() benchmarks
69b2fa7f3SIngo Molnar *
79b2fa7f3SIngo Molnar * Written by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
89b2fa7f3SIngo Molnar */
99b2fa7f3SIngo Molnar
10c2a218c6SArnaldo Carvalho de Melo #include "debug.h"
1191854f9aSArnaldo Carvalho de Melo #include "../perf-sys.h"
124b6ab94eSJosh Poimboeuf #include <subcmd/parse-options.h>
139b2fa7f3SIngo Molnar #include "../util/header.h"
149b2fa7f3SIngo Molnar #include "../util/cloexec.h"
15a067558eSArnaldo Carvalho de Melo #include "../util/string2.h"
169b2fa7f3SIngo Molnar #include "bench.h"
179b2fa7f3SIngo Molnar #include "mem-memcpy-arch.h"
189b2fa7f3SIngo Molnar #include "mem-memset-arch.h"
199b2fa7f3SIngo Molnar
209b2fa7f3SIngo Molnar #include <stdio.h>
219b2fa7f3SIngo Molnar #include <stdlib.h>
229b2fa7f3SIngo Molnar #include <string.h>
2391854f9aSArnaldo Carvalho de Melo #include <unistd.h>
249b2fa7f3SIngo Molnar #include <sys/time.h>
259b2fa7f3SIngo Molnar #include <errno.h>
26f2b91be7SArnaldo Carvalho de Melo #include <linux/time64.h>
277f7c536fSArnaldo Carvalho de Melo #include <linux/zalloc.h>
289b2fa7f3SIngo Molnar
299b2fa7f3SIngo Molnar #define K 1024
309b2fa7f3SIngo Molnar
31a69b4f74SIngo Molnar static const char *size_str = "1MB";
322f211c84SIngo Molnar static const char *function_str = "all";
33b0d22e52SIngo Molnar static int nr_loops = 1;
34b14f2d35SIngo Molnar static bool use_cycles;
35b14f2d35SIngo Molnar static int cycles_fd;
369b2fa7f3SIngo Molnar
379b2fa7f3SIngo Molnar static const struct option options[] = {
38b0d22e52SIngo Molnar OPT_STRING('s', "size", &size_str, "1MB",
39a69b4f74SIngo Molnar "Specify the size of the memory buffers. "
4013b1fdceSIngo Molnar "Available units: B, KB, MB, GB and TB (case insensitive)"),
4113b1fdceSIngo Molnar
422f211c84SIngo Molnar OPT_STRING('f', "function", &function_str, "all",
432f211c84SIngo Molnar "Specify the function to run, \"all\" runs all available functions, \"help\" lists them"),
4413b1fdceSIngo Molnar
45b0d22e52SIngo Molnar OPT_INTEGER('l', "nr_loops", &nr_loops,
46b0d22e52SIngo Molnar "Specify the number of loops to run. (default: 1)"),
4713b1fdceSIngo Molnar
48b14f2d35SIngo Molnar OPT_BOOLEAN('c', "cycles", &use_cycles,
49b14f2d35SIngo Molnar "Use a cycles event instead of gettimeofday() to measure performance"),
5013b1fdceSIngo Molnar
519b2fa7f3SIngo Molnar OPT_END()
529b2fa7f3SIngo Molnar };
539b2fa7f3SIngo Molnar
549b2fa7f3SIngo Molnar typedef void *(*memcpy_t)(void *, const void *, size_t);
559b2fa7f3SIngo Molnar typedef void *(*memset_t)(void *, int, size_t);
569b2fa7f3SIngo Molnar
572f211c84SIngo Molnar struct function {
589b2fa7f3SIngo Molnar const char *name;
599b2fa7f3SIngo Molnar const char *desc;
609b2fa7f3SIngo Molnar union {
619b2fa7f3SIngo Molnar memcpy_t memcpy;
629b2fa7f3SIngo Molnar memset_t memset;
639b2fa7f3SIngo Molnar } fn;
649b2fa7f3SIngo Molnar };
659b2fa7f3SIngo Molnar
669b2fa7f3SIngo Molnar static struct perf_event_attr cycle_attr = {
679b2fa7f3SIngo Molnar .type = PERF_TYPE_HARDWARE,
689b2fa7f3SIngo Molnar .config = PERF_COUNT_HW_CPU_CYCLES
699b2fa7f3SIngo Molnar };
709b2fa7f3SIngo Molnar
init_cycles(void)71c2a218c6SArnaldo Carvalho de Melo static int init_cycles(void)
729b2fa7f3SIngo Molnar {
73b14f2d35SIngo Molnar cycles_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1, perf_event_open_cloexec_flag());
749b2fa7f3SIngo Molnar
75c2a218c6SArnaldo Carvalho de Melo if (cycles_fd < 0 && errno == ENOSYS) {
76c2a218c6SArnaldo Carvalho de Melo pr_debug("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
77c2a218c6SArnaldo Carvalho de Melo return -1;
78c2a218c6SArnaldo Carvalho de Melo }
79c2a218c6SArnaldo Carvalho de Melo
80c2a218c6SArnaldo Carvalho de Melo return cycles_fd;
819b2fa7f3SIngo Molnar }
829b2fa7f3SIngo Molnar
get_cycles(void)83b14f2d35SIngo Molnar static u64 get_cycles(void)
849b2fa7f3SIngo Molnar {
859b2fa7f3SIngo Molnar int ret;
869b2fa7f3SIngo Molnar u64 clk;
879b2fa7f3SIngo Molnar
88b14f2d35SIngo Molnar ret = read(cycles_fd, &clk, sizeof(u64));
899b2fa7f3SIngo Molnar BUG_ON(ret != sizeof(u64));
909b2fa7f3SIngo Molnar
919b2fa7f3SIngo Molnar return clk;
929b2fa7f3SIngo Molnar }
939b2fa7f3SIngo Molnar
timeval2double(struct timeval * ts)949b2fa7f3SIngo Molnar static double timeval2double(struct timeval *ts)
959b2fa7f3SIngo Molnar {
96f2b91be7SArnaldo Carvalho de Melo return (double)ts->tv_sec + (double)ts->tv_usec / (double)USEC_PER_SEC;
979b2fa7f3SIngo Molnar }
989b2fa7f3SIngo Molnar
999b2fa7f3SIngo Molnar #define print_bps(x) do { \
1009b2fa7f3SIngo Molnar if (x < K) \
10113b1fdceSIngo Molnar printf(" %14lf bytes/sec\n", x); \
1029b2fa7f3SIngo Molnar else if (x < K * K) \
10313b1fdceSIngo Molnar printf(" %14lfd KB/sec\n", x / K); \
1049b2fa7f3SIngo Molnar else if (x < K * K * K) \
10513b1fdceSIngo Molnar printf(" %14lf MB/sec\n", x / K / K); \
1069b2fa7f3SIngo Molnar else \
10713b1fdceSIngo Molnar printf(" %14lf GB/sec\n", x / K / K / K); \
1089b2fa7f3SIngo Molnar } while (0)
1099b2fa7f3SIngo Molnar
1109b2fa7f3SIngo Molnar struct bench_mem_info {
1112f211c84SIngo Molnar const struct function *functions;
11247b5757bSArnaldo Carvalho de Melo u64 (*do_cycles)(const struct function *r, size_t size, void *src, void *dst);
11347b5757bSArnaldo Carvalho de Melo double (*do_gettimeofday)(const struct function *r, size_t size, void *src, void *dst);
1149b2fa7f3SIngo Molnar const char *const *usage;
11547b5757bSArnaldo Carvalho de Melo bool alloc_src;
1169b2fa7f3SIngo Molnar };
1179b2fa7f3SIngo Molnar
__bench_mem_function(struct bench_mem_info * info,int r_idx,size_t size,double size_total)1182f211c84SIngo Molnar static void __bench_mem_function(struct bench_mem_info *info, int r_idx, size_t size, double size_total)
1199b2fa7f3SIngo Molnar {
1202f211c84SIngo Molnar const struct function *r = &info->functions[r_idx];
1216db175c7SIngo Molnar double result_bps = 0.0;
122b14f2d35SIngo Molnar u64 result_cycles = 0;
12347b5757bSArnaldo Carvalho de Melo void *src = NULL, *dst = zalloc(size);
1249b2fa7f3SIngo Molnar
1252f211c84SIngo Molnar printf("# function '%s' (%s)\n", r->name, r->desc);
1269b2fa7f3SIngo Molnar
12747b5757bSArnaldo Carvalho de Melo if (dst == NULL)
12847b5757bSArnaldo Carvalho de Melo goto out_alloc_failed;
12947b5757bSArnaldo Carvalho de Melo
13047b5757bSArnaldo Carvalho de Melo if (info->alloc_src) {
13147b5757bSArnaldo Carvalho de Melo src = zalloc(size);
13247b5757bSArnaldo Carvalho de Melo if (src == NULL)
13347b5757bSArnaldo Carvalho de Melo goto out_alloc_failed;
13447b5757bSArnaldo Carvalho de Melo }
13547b5757bSArnaldo Carvalho de Melo
1369b2fa7f3SIngo Molnar if (bench_format == BENCH_FORMAT_DEFAULT)
13713b1fdceSIngo Molnar printf("# Copying %s bytes ...\n\n", size_str);
1389b2fa7f3SIngo Molnar
139b14f2d35SIngo Molnar if (use_cycles) {
14047b5757bSArnaldo Carvalho de Melo result_cycles = info->do_cycles(r, size, src, dst);
1419b2fa7f3SIngo Molnar } else {
14247b5757bSArnaldo Carvalho de Melo result_bps = info->do_gettimeofday(r, size, src, dst);
1439b2fa7f3SIngo Molnar }
1449b2fa7f3SIngo Molnar
1459b2fa7f3SIngo Molnar switch (bench_format) {
1469b2fa7f3SIngo Molnar case BENCH_FORMAT_DEFAULT:
147b14f2d35SIngo Molnar if (use_cycles) {
14813b1fdceSIngo Molnar printf(" %14lf cycles/byte\n", (double)result_cycles/size_total);
1499b2fa7f3SIngo Molnar } else {
1506db175c7SIngo Molnar print_bps(result_bps);
1519b2fa7f3SIngo Molnar }
1526db175c7SIngo Molnar break;
1539b2fa7f3SIngo Molnar
1549b2fa7f3SIngo Molnar case BENCH_FORMAT_SIMPLE:
155b14f2d35SIngo Molnar if (use_cycles) {
156a69b4f74SIngo Molnar printf("%lf\n", (double)result_cycles/size_total);
1579b2fa7f3SIngo Molnar } else {
1586db175c7SIngo Molnar printf("%lf\n", result_bps);
1599b2fa7f3SIngo Molnar }
1609b2fa7f3SIngo Molnar break;
1616db175c7SIngo Molnar
1629b2fa7f3SIngo Molnar default:
1636db175c7SIngo Molnar BUG_ON(1);
1649b2fa7f3SIngo Molnar break;
1659b2fa7f3SIngo Molnar }
16647b5757bSArnaldo Carvalho de Melo
16747b5757bSArnaldo Carvalho de Melo out_free:
16847b5757bSArnaldo Carvalho de Melo free(src);
16947b5757bSArnaldo Carvalho de Melo free(dst);
17047b5757bSArnaldo Carvalho de Melo return;
17147b5757bSArnaldo Carvalho de Melo out_alloc_failed:
17247b5757bSArnaldo Carvalho de Melo printf("# Memory allocation failed - maybe size (%s) is too large?\n", size_str);
17347b5757bSArnaldo Carvalho de Melo goto out_free;
1749b2fa7f3SIngo Molnar }
1759b2fa7f3SIngo Molnar
bench_mem_common(int argc,const char ** argv,struct bench_mem_info * info)1769b2fa7f3SIngo Molnar static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *info)
1779b2fa7f3SIngo Molnar {
1789b2fa7f3SIngo Molnar int i;
179a69b4f74SIngo Molnar size_t size;
180a69b4f74SIngo Molnar double size_total;
1819b2fa7f3SIngo Molnar
1829b2fa7f3SIngo Molnar argc = parse_options(argc, argv, options, info->usage, 0);
1839b2fa7f3SIngo Molnar
184c2a218c6SArnaldo Carvalho de Melo if (use_cycles) {
185c2a218c6SArnaldo Carvalho de Melo i = init_cycles();
186c2a218c6SArnaldo Carvalho de Melo if (i < 0) {
187c2a218c6SArnaldo Carvalho de Melo fprintf(stderr, "Failed to open cycles counter\n");
188c2a218c6SArnaldo Carvalho de Melo return i;
189c2a218c6SArnaldo Carvalho de Melo }
190c2a218c6SArnaldo Carvalho de Melo }
1919b2fa7f3SIngo Molnar
192a69b4f74SIngo Molnar size = (size_t)perf_atoll((char *)size_str);
193b0d22e52SIngo Molnar size_total = (double)size * nr_loops;
1949b2fa7f3SIngo Molnar
195a69b4f74SIngo Molnar if ((s64)size <= 0) {
196a69b4f74SIngo Molnar fprintf(stderr, "Invalid size:%s\n", size_str);
1979b2fa7f3SIngo Molnar return 1;
1989b2fa7f3SIngo Molnar }
1999b2fa7f3SIngo Molnar
2002f211c84SIngo Molnar if (!strncmp(function_str, "all", 3)) {
2012f211c84SIngo Molnar for (i = 0; info->functions[i].name; i++)
2022f211c84SIngo Molnar __bench_mem_function(info, i, size, size_total);
2039b2fa7f3SIngo Molnar return 0;
2049b2fa7f3SIngo Molnar }
2059b2fa7f3SIngo Molnar
2062f211c84SIngo Molnar for (i = 0; info->functions[i].name; i++) {
2072f211c84SIngo Molnar if (!strcmp(info->functions[i].name, function_str))
2089b2fa7f3SIngo Molnar break;
2099b2fa7f3SIngo Molnar }
2102f211c84SIngo Molnar if (!info->functions[i].name) {
2112f211c84SIngo Molnar if (strcmp(function_str, "help") && strcmp(function_str, "h"))
2122f211c84SIngo Molnar printf("Unknown function: %s\n", function_str);
2132f211c84SIngo Molnar printf("Available functions:\n");
2142f211c84SIngo Molnar for (i = 0; info->functions[i].name; i++) {
2159b2fa7f3SIngo Molnar printf("\t%s ... %s\n",
2162f211c84SIngo Molnar info->functions[i].name, info->functions[i].desc);
2179b2fa7f3SIngo Molnar }
2189b2fa7f3SIngo Molnar return 1;
2199b2fa7f3SIngo Molnar }
2209b2fa7f3SIngo Molnar
2212f211c84SIngo Molnar __bench_mem_function(info, i, size, size_total);
2229b2fa7f3SIngo Molnar
2239b2fa7f3SIngo Molnar return 0;
2249b2fa7f3SIngo Molnar }
2259b2fa7f3SIngo Molnar
memcpy_prefault(memcpy_t fn,size_t size,void * src,void * dst)226*1beaef29SVincent Whitchurch static void memcpy_prefault(memcpy_t fn, size_t size, void *src, void *dst)
2279b2fa7f3SIngo Molnar {
22847b5757bSArnaldo Carvalho de Melo /* Make sure to always prefault zero pages even if MMAP_THRESH is crossed: */
22947b5757bSArnaldo Carvalho de Melo memset(src, 0, size);
2309b2fa7f3SIngo Molnar
2316db175c7SIngo Molnar /*
2326db175c7SIngo Molnar * We prefault the freshly allocated memory range here,
2336db175c7SIngo Molnar * to not measure page fault overhead:
2346db175c7SIngo Molnar */
235a69b4f74SIngo Molnar fn(dst, src, size);
236*1beaef29SVincent Whitchurch }
237*1beaef29SVincent Whitchurch
do_memcpy_cycles(const struct function * r,size_t size,void * src,void * dst)238*1beaef29SVincent Whitchurch static u64 do_memcpy_cycles(const struct function *r, size_t size, void *src, void *dst)
239*1beaef29SVincent Whitchurch {
240*1beaef29SVincent Whitchurch u64 cycle_start = 0ULL, cycle_end = 0ULL;
241*1beaef29SVincent Whitchurch memcpy_t fn = r->fn.memcpy;
242*1beaef29SVincent Whitchurch int i;
243*1beaef29SVincent Whitchurch
244*1beaef29SVincent Whitchurch memcpy_prefault(fn, size, src, dst);
2459b2fa7f3SIngo Molnar
246b14f2d35SIngo Molnar cycle_start = get_cycles();
247b0d22e52SIngo Molnar for (i = 0; i < nr_loops; ++i)
248a69b4f74SIngo Molnar fn(dst, src, size);
249b14f2d35SIngo Molnar cycle_end = get_cycles();
2509b2fa7f3SIngo Molnar
2519b2fa7f3SIngo Molnar return cycle_end - cycle_start;
2529b2fa7f3SIngo Molnar }
2539b2fa7f3SIngo Molnar
do_memcpy_gettimeofday(const struct function * r,size_t size,void * src,void * dst)25447b5757bSArnaldo Carvalho de Melo static double do_memcpy_gettimeofday(const struct function *r, size_t size, void *src, void *dst)
2559b2fa7f3SIngo Molnar {
2569b2fa7f3SIngo Molnar struct timeval tv_start, tv_end, tv_diff;
2579b2fa7f3SIngo Molnar memcpy_t fn = r->fn.memcpy;
2589b2fa7f3SIngo Molnar int i;
2599b2fa7f3SIngo Molnar
260*1beaef29SVincent Whitchurch memcpy_prefault(fn, size, src, dst);
2619b2fa7f3SIngo Molnar
2629b2fa7f3SIngo Molnar BUG_ON(gettimeofday(&tv_start, NULL));
263b0d22e52SIngo Molnar for (i = 0; i < nr_loops; ++i)
264a69b4f74SIngo Molnar fn(dst, src, size);
2659b2fa7f3SIngo Molnar BUG_ON(gettimeofday(&tv_end, NULL));
2669b2fa7f3SIngo Molnar
2679b2fa7f3SIngo Molnar timersub(&tv_end, &tv_start, &tv_diff);
2689b2fa7f3SIngo Molnar
269b0d22e52SIngo Molnar return (double)(((double)size * nr_loops) / timeval2double(&tv_diff));
2709b2fa7f3SIngo Molnar }
2719b2fa7f3SIngo Molnar
2722f211c84SIngo Molnar struct function memcpy_functions[] = {
2735dd93304SIngo Molnar { .name = "default",
2745dd93304SIngo Molnar .desc = "Default memcpy() provided by glibc",
2755dd93304SIngo Molnar .fn.memcpy = memcpy },
2765dd93304SIngo Molnar
2775dd93304SIngo Molnar #ifdef HAVE_ARCH_X86_64_SUPPORT
2785dd93304SIngo Molnar # define MEMCPY_FN(_fn, _name, _desc) {.name = _name, .desc = _desc, .fn.memcpy = _fn},
2795dd93304SIngo Molnar # include "mem-memcpy-x86-64-asm-def.h"
2805dd93304SIngo Molnar # undef MEMCPY_FN
2815dd93304SIngo Molnar #endif
2825dd93304SIngo Molnar
283a4c6a3e8SArnaldo Carvalho de Melo { .name = NULL, }
2845dd93304SIngo Molnar };
2855dd93304SIngo Molnar
2865dd93304SIngo Molnar static const char * const bench_mem_memcpy_usage[] = {
2875dd93304SIngo Molnar "perf bench mem memcpy <options>",
2885dd93304SIngo Molnar NULL
2895dd93304SIngo Molnar };
2905dd93304SIngo Molnar
bench_mem_memcpy(int argc,const char ** argv)291b0ad8ea6SArnaldo Carvalho de Melo int bench_mem_memcpy(int argc, const char **argv)
2929b2fa7f3SIngo Molnar {
2939b2fa7f3SIngo Molnar struct bench_mem_info info = {
2942f211c84SIngo Molnar .functions = memcpy_functions,
295b14f2d35SIngo Molnar .do_cycles = do_memcpy_cycles,
2969b2fa7f3SIngo Molnar .do_gettimeofday = do_memcpy_gettimeofday,
2979b2fa7f3SIngo Molnar .usage = bench_mem_memcpy_usage,
29847b5757bSArnaldo Carvalho de Melo .alloc_src = true,
2999b2fa7f3SIngo Molnar };
3009b2fa7f3SIngo Molnar
3019b2fa7f3SIngo Molnar return bench_mem_common(argc, argv, &info);
3029b2fa7f3SIngo Molnar }
3039b2fa7f3SIngo Molnar
do_memset_cycles(const struct function * r,size_t size,void * src __maybe_unused,void * dst)30447b5757bSArnaldo Carvalho de Melo static u64 do_memset_cycles(const struct function *r, size_t size, void *src __maybe_unused, void *dst)
3059b2fa7f3SIngo Molnar {
3069b2fa7f3SIngo Molnar u64 cycle_start = 0ULL, cycle_end = 0ULL;
3079b2fa7f3SIngo Molnar memset_t fn = r->fn.memset;
3089b2fa7f3SIngo Molnar int i;
3099b2fa7f3SIngo Molnar
3106db175c7SIngo Molnar /*
3116db175c7SIngo Molnar * We prefault the freshly allocated memory range here,
3126db175c7SIngo Molnar * to not measure page fault overhead:
3136db175c7SIngo Molnar */
314a69b4f74SIngo Molnar fn(dst, -1, size);
3159b2fa7f3SIngo Molnar
316b14f2d35SIngo Molnar cycle_start = get_cycles();
317b0d22e52SIngo Molnar for (i = 0; i < nr_loops; ++i)
318a69b4f74SIngo Molnar fn(dst, i, size);
319b14f2d35SIngo Molnar cycle_end = get_cycles();
3209b2fa7f3SIngo Molnar
3219b2fa7f3SIngo Molnar return cycle_end - cycle_start;
3229b2fa7f3SIngo Molnar }
3239b2fa7f3SIngo Molnar
do_memset_gettimeofday(const struct function * r,size_t size,void * src __maybe_unused,void * dst)32447b5757bSArnaldo Carvalho de Melo static double do_memset_gettimeofday(const struct function *r, size_t size, void *src __maybe_unused, void *dst)
3259b2fa7f3SIngo Molnar {
3269b2fa7f3SIngo Molnar struct timeval tv_start, tv_end, tv_diff;
3279b2fa7f3SIngo Molnar memset_t fn = r->fn.memset;
3289b2fa7f3SIngo Molnar int i;
3299b2fa7f3SIngo Molnar
3306db175c7SIngo Molnar /*
3316db175c7SIngo Molnar * We prefault the freshly allocated memory range here,
3326db175c7SIngo Molnar * to not measure page fault overhead:
3336db175c7SIngo Molnar */
334a69b4f74SIngo Molnar fn(dst, -1, size);
3359b2fa7f3SIngo Molnar
3369b2fa7f3SIngo Molnar BUG_ON(gettimeofday(&tv_start, NULL));
337b0d22e52SIngo Molnar for (i = 0; i < nr_loops; ++i)
338a69b4f74SIngo Molnar fn(dst, i, size);
3399b2fa7f3SIngo Molnar BUG_ON(gettimeofday(&tv_end, NULL));
3409b2fa7f3SIngo Molnar
3419b2fa7f3SIngo Molnar timersub(&tv_end, &tv_start, &tv_diff);
3429b2fa7f3SIngo Molnar
343b0d22e52SIngo Molnar return (double)(((double)size * nr_loops) / timeval2double(&tv_diff));
3449b2fa7f3SIngo Molnar }
3459b2fa7f3SIngo Molnar
3469b2fa7f3SIngo Molnar static const char * const bench_mem_memset_usage[] = {
3479b2fa7f3SIngo Molnar "perf bench mem memset <options>",
3489b2fa7f3SIngo Molnar NULL
3499b2fa7f3SIngo Molnar };
3509b2fa7f3SIngo Molnar
3512f211c84SIngo Molnar static const struct function memset_functions[] = {
3529b2fa7f3SIngo Molnar { .name = "default",
3539b2fa7f3SIngo Molnar .desc = "Default memset() provided by glibc",
3549b2fa7f3SIngo Molnar .fn.memset = memset },
3559b2fa7f3SIngo Molnar
3569b2fa7f3SIngo Molnar #ifdef HAVE_ARCH_X86_64_SUPPORT
3579b2fa7f3SIngo Molnar # define MEMSET_FN(_fn, _name, _desc) { .name = _name, .desc = _desc, .fn.memset = _fn },
3589b2fa7f3SIngo Molnar # include "mem-memset-x86-64-asm-def.h"
3599b2fa7f3SIngo Molnar # undef MEMSET_FN
3609b2fa7f3SIngo Molnar #endif
3619b2fa7f3SIngo Molnar
362a4c6a3e8SArnaldo Carvalho de Melo { .name = NULL, }
3639b2fa7f3SIngo Molnar };
3649b2fa7f3SIngo Molnar
bench_mem_memset(int argc,const char ** argv)365b0ad8ea6SArnaldo Carvalho de Melo int bench_mem_memset(int argc, const char **argv)
3669b2fa7f3SIngo Molnar {
3679b2fa7f3SIngo Molnar struct bench_mem_info info = {
3682f211c84SIngo Molnar .functions = memset_functions,
369b14f2d35SIngo Molnar .do_cycles = do_memset_cycles,
3709b2fa7f3SIngo Molnar .do_gettimeofday = do_memset_gettimeofday,
3719b2fa7f3SIngo Molnar .usage = bench_mem_memset_usage,
3729b2fa7f3SIngo Molnar };
3739b2fa7f3SIngo Molnar
3749b2fa7f3SIngo Molnar return bench_mem_common(argc, argv, &info);
3759b2fa7f3SIngo Molnar }
376