18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * mem-memcpy.c
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Simple memcpy() and memset() benchmarks
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Written by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#include "debug.h"
118c2ecf20Sopenharmony_ci#include "../perf-sys.h"
128c2ecf20Sopenharmony_ci#include <subcmd/parse-options.h>
138c2ecf20Sopenharmony_ci#include "../util/header.h"
148c2ecf20Sopenharmony_ci#include "../util/cloexec.h"
158c2ecf20Sopenharmony_ci#include "../util/string2.h"
168c2ecf20Sopenharmony_ci#include "bench.h"
178c2ecf20Sopenharmony_ci#include "mem-memcpy-arch.h"
188c2ecf20Sopenharmony_ci#include "mem-memset-arch.h"
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci#include <stdio.h>
218c2ecf20Sopenharmony_ci#include <stdlib.h>
228c2ecf20Sopenharmony_ci#include <string.h>
238c2ecf20Sopenharmony_ci#include <unistd.h>
248c2ecf20Sopenharmony_ci#include <sys/time.h>
258c2ecf20Sopenharmony_ci#include <errno.h>
268c2ecf20Sopenharmony_ci#include <linux/time64.h>
278c2ecf20Sopenharmony_ci#include <linux/zalloc.h>
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci#define K 1024
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_cistatic const char	*size_str	= "1MB";
328c2ecf20Sopenharmony_cistatic const char	*function_str	= "all";
338c2ecf20Sopenharmony_cistatic int		nr_loops	= 1;
348c2ecf20Sopenharmony_cistatic bool		use_cycles;
358c2ecf20Sopenharmony_cistatic int		cycles_fd;
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_cistatic const struct option options[] = {
388c2ecf20Sopenharmony_ci	OPT_STRING('s', "size", &size_str, "1MB",
398c2ecf20Sopenharmony_ci		    "Specify the size of the memory buffers. "
408c2ecf20Sopenharmony_ci		    "Available units: B, KB, MB, GB and TB (case insensitive)"),
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci	OPT_STRING('f', "function", &function_str, "all",
438c2ecf20Sopenharmony_ci		    "Specify the function to run, \"all\" runs all available functions, \"help\" lists them"),
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci	OPT_INTEGER('l', "nr_loops", &nr_loops,
468c2ecf20Sopenharmony_ci		    "Specify the number of loops to run. (default: 1)"),
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci	OPT_BOOLEAN('c', "cycles", &use_cycles,
498c2ecf20Sopenharmony_ci		    "Use a cycles event instead of gettimeofday() to measure performance"),
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci	OPT_END()
528c2ecf20Sopenharmony_ci};
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_citypedef void *(*memcpy_t)(void *, const void *, size_t);
558c2ecf20Sopenharmony_citypedef void *(*memset_t)(void *, int, size_t);
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_cistruct function {
588c2ecf20Sopenharmony_ci	const char *name;
598c2ecf20Sopenharmony_ci	const char *desc;
608c2ecf20Sopenharmony_ci	union {
618c2ecf20Sopenharmony_ci		memcpy_t memcpy;
628c2ecf20Sopenharmony_ci		memset_t memset;
638c2ecf20Sopenharmony_ci	} fn;
648c2ecf20Sopenharmony_ci};
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_cistatic struct perf_event_attr cycle_attr = {
678c2ecf20Sopenharmony_ci	.type		= PERF_TYPE_HARDWARE,
688c2ecf20Sopenharmony_ci	.config		= PERF_COUNT_HW_CPU_CYCLES
698c2ecf20Sopenharmony_ci};
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_cistatic int init_cycles(void)
728c2ecf20Sopenharmony_ci{
738c2ecf20Sopenharmony_ci	cycles_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1, perf_event_open_cloexec_flag());
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci	if (cycles_fd < 0 && errno == ENOSYS) {
768c2ecf20Sopenharmony_ci		pr_debug("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
778c2ecf20Sopenharmony_ci		return -1;
788c2ecf20Sopenharmony_ci	}
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci	return cycles_fd;
818c2ecf20Sopenharmony_ci}
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_cistatic u64 get_cycles(void)
848c2ecf20Sopenharmony_ci{
858c2ecf20Sopenharmony_ci	int ret;
868c2ecf20Sopenharmony_ci	u64 clk;
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci	ret = read(cycles_fd, &clk, sizeof(u64));
898c2ecf20Sopenharmony_ci	BUG_ON(ret != sizeof(u64));
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ci	return clk;
928c2ecf20Sopenharmony_ci}
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_cistatic double timeval2double(struct timeval *ts)
958c2ecf20Sopenharmony_ci{
968c2ecf20Sopenharmony_ci	return (double)ts->tv_sec + (double)ts->tv_usec / (double)USEC_PER_SEC;
978c2ecf20Sopenharmony_ci}
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci#define print_bps(x) do {						\
1008c2ecf20Sopenharmony_ci		if (x < K)						\
1018c2ecf20Sopenharmony_ci			printf(" %14lf bytes/sec\n", x);		\
1028c2ecf20Sopenharmony_ci		else if (x < K * K)					\
1038c2ecf20Sopenharmony_ci			printf(" %14lfd KB/sec\n", x / K);		\
1048c2ecf20Sopenharmony_ci		else if (x < K * K * K)					\
1058c2ecf20Sopenharmony_ci			printf(" %14lf MB/sec\n", x / K / K);		\
1068c2ecf20Sopenharmony_ci		else							\
1078c2ecf20Sopenharmony_ci			printf(" %14lf GB/sec\n", x / K / K / K);	\
1088c2ecf20Sopenharmony_ci	} while (0)
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_cistruct bench_mem_info {
1118c2ecf20Sopenharmony_ci	const struct function *functions;
1128c2ecf20Sopenharmony_ci	u64 (*do_cycles)(const struct function *r, size_t size, void *src, void *dst);
1138c2ecf20Sopenharmony_ci	double (*do_gettimeofday)(const struct function *r, size_t size, void *src, void *dst);
1148c2ecf20Sopenharmony_ci	const char *const *usage;
1158c2ecf20Sopenharmony_ci	bool alloc_src;
1168c2ecf20Sopenharmony_ci};
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_cistatic void __bench_mem_function(struct bench_mem_info *info, int r_idx, size_t size, double size_total)
1198c2ecf20Sopenharmony_ci{
1208c2ecf20Sopenharmony_ci	const struct function *r = &info->functions[r_idx];
1218c2ecf20Sopenharmony_ci	double result_bps = 0.0;
1228c2ecf20Sopenharmony_ci	u64 result_cycles = 0;
1238c2ecf20Sopenharmony_ci	void *src = NULL, *dst = zalloc(size);
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci	printf("# function '%s' (%s)\n", r->name, r->desc);
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_ci	if (dst == NULL)
1288c2ecf20Sopenharmony_ci		goto out_alloc_failed;
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci	if (info->alloc_src) {
1318c2ecf20Sopenharmony_ci		src = zalloc(size);
1328c2ecf20Sopenharmony_ci		if (src == NULL)
1338c2ecf20Sopenharmony_ci			goto out_alloc_failed;
1348c2ecf20Sopenharmony_ci	}
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ci	if (bench_format == BENCH_FORMAT_DEFAULT)
1378c2ecf20Sopenharmony_ci		printf("# Copying %s bytes ...\n\n", size_str);
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_ci	if (use_cycles) {
1408c2ecf20Sopenharmony_ci		result_cycles = info->do_cycles(r, size, src, dst);
1418c2ecf20Sopenharmony_ci	} else {
1428c2ecf20Sopenharmony_ci		result_bps = info->do_gettimeofday(r, size, src, dst);
1438c2ecf20Sopenharmony_ci	}
1448c2ecf20Sopenharmony_ci
1458c2ecf20Sopenharmony_ci	switch (bench_format) {
1468c2ecf20Sopenharmony_ci	case BENCH_FORMAT_DEFAULT:
1478c2ecf20Sopenharmony_ci		if (use_cycles) {
1488c2ecf20Sopenharmony_ci			printf(" %14lf cycles/byte\n", (double)result_cycles/size_total);
1498c2ecf20Sopenharmony_ci		} else {
1508c2ecf20Sopenharmony_ci			print_bps(result_bps);
1518c2ecf20Sopenharmony_ci		}
1528c2ecf20Sopenharmony_ci		break;
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci	case BENCH_FORMAT_SIMPLE:
1558c2ecf20Sopenharmony_ci		if (use_cycles) {
1568c2ecf20Sopenharmony_ci			printf("%lf\n", (double)result_cycles/size_total);
1578c2ecf20Sopenharmony_ci		} else {
1588c2ecf20Sopenharmony_ci			printf("%lf\n", result_bps);
1598c2ecf20Sopenharmony_ci		}
1608c2ecf20Sopenharmony_ci		break;
1618c2ecf20Sopenharmony_ci
1628c2ecf20Sopenharmony_ci	default:
1638c2ecf20Sopenharmony_ci		BUG_ON(1);
1648c2ecf20Sopenharmony_ci		break;
1658c2ecf20Sopenharmony_ci	}
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_ciout_free:
1688c2ecf20Sopenharmony_ci	free(src);
1698c2ecf20Sopenharmony_ci	free(dst);
1708c2ecf20Sopenharmony_ci	return;
1718c2ecf20Sopenharmony_ciout_alloc_failed:
1728c2ecf20Sopenharmony_ci	printf("# Memory allocation failed - maybe size (%s) is too large?\n", size_str);
1738c2ecf20Sopenharmony_ci	goto out_free;
1748c2ecf20Sopenharmony_ci}
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_cistatic int bench_mem_common(int argc, const char **argv, struct bench_mem_info *info)
1778c2ecf20Sopenharmony_ci{
1788c2ecf20Sopenharmony_ci	int i;
1798c2ecf20Sopenharmony_ci	size_t size;
1808c2ecf20Sopenharmony_ci	double size_total;
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci	argc = parse_options(argc, argv, options, info->usage, 0);
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_ci	if (use_cycles) {
1858c2ecf20Sopenharmony_ci		i = init_cycles();
1868c2ecf20Sopenharmony_ci		if (i < 0) {
1878c2ecf20Sopenharmony_ci			fprintf(stderr, "Failed to open cycles counter\n");
1888c2ecf20Sopenharmony_ci			return i;
1898c2ecf20Sopenharmony_ci		}
1908c2ecf20Sopenharmony_ci	}
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_ci	size = (size_t)perf_atoll((char *)size_str);
1938c2ecf20Sopenharmony_ci	size_total = (double)size * nr_loops;
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ci	if ((s64)size <= 0) {
1968c2ecf20Sopenharmony_ci		fprintf(stderr, "Invalid size:%s\n", size_str);
1978c2ecf20Sopenharmony_ci		return 1;
1988c2ecf20Sopenharmony_ci	}
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci	if (!strncmp(function_str, "all", 3)) {
2018c2ecf20Sopenharmony_ci		for (i = 0; info->functions[i].name; i++)
2028c2ecf20Sopenharmony_ci			__bench_mem_function(info, i, size, size_total);
2038c2ecf20Sopenharmony_ci		return 0;
2048c2ecf20Sopenharmony_ci	}
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_ci	for (i = 0; info->functions[i].name; i++) {
2078c2ecf20Sopenharmony_ci		if (!strcmp(info->functions[i].name, function_str))
2088c2ecf20Sopenharmony_ci			break;
2098c2ecf20Sopenharmony_ci	}
2108c2ecf20Sopenharmony_ci	if (!info->functions[i].name) {
2118c2ecf20Sopenharmony_ci		if (strcmp(function_str, "help") && strcmp(function_str, "h"))
2128c2ecf20Sopenharmony_ci			printf("Unknown function: %s\n", function_str);
2138c2ecf20Sopenharmony_ci		printf("Available functions:\n");
2148c2ecf20Sopenharmony_ci		for (i = 0; info->functions[i].name; i++) {
2158c2ecf20Sopenharmony_ci			printf("\t%s ... %s\n",
2168c2ecf20Sopenharmony_ci			       info->functions[i].name, info->functions[i].desc);
2178c2ecf20Sopenharmony_ci		}
2188c2ecf20Sopenharmony_ci		return 1;
2198c2ecf20Sopenharmony_ci	}
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_ci	__bench_mem_function(info, i, size, size_total);
2228c2ecf20Sopenharmony_ci
2238c2ecf20Sopenharmony_ci	return 0;
2248c2ecf20Sopenharmony_ci}
2258c2ecf20Sopenharmony_ci
2268c2ecf20Sopenharmony_cistatic void memcpy_prefault(memcpy_t fn, size_t size, void *src, void *dst)
2278c2ecf20Sopenharmony_ci{
2288c2ecf20Sopenharmony_ci	/* Make sure to always prefault zero pages even if MMAP_THRESH is crossed: */
2298c2ecf20Sopenharmony_ci	memset(src, 0, size);
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ci	/*
2328c2ecf20Sopenharmony_ci	 * We prefault the freshly allocated memory range here,
2338c2ecf20Sopenharmony_ci	 * to not measure page fault overhead:
2348c2ecf20Sopenharmony_ci	 */
2358c2ecf20Sopenharmony_ci	fn(dst, src, size);
2368c2ecf20Sopenharmony_ci}
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_cistatic u64 do_memcpy_cycles(const struct function *r, size_t size, void *src, void *dst)
2398c2ecf20Sopenharmony_ci{
2408c2ecf20Sopenharmony_ci	u64 cycle_start = 0ULL, cycle_end = 0ULL;
2418c2ecf20Sopenharmony_ci	memcpy_t fn = r->fn.memcpy;
2428c2ecf20Sopenharmony_ci	int i;
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_ci	memcpy_prefault(fn, size, src, dst);
2458c2ecf20Sopenharmony_ci
2468c2ecf20Sopenharmony_ci	cycle_start = get_cycles();
2478c2ecf20Sopenharmony_ci	for (i = 0; i < nr_loops; ++i)
2488c2ecf20Sopenharmony_ci		fn(dst, src, size);
2498c2ecf20Sopenharmony_ci	cycle_end = get_cycles();
2508c2ecf20Sopenharmony_ci
2518c2ecf20Sopenharmony_ci	return cycle_end - cycle_start;
2528c2ecf20Sopenharmony_ci}
2538c2ecf20Sopenharmony_ci
2548c2ecf20Sopenharmony_cistatic double do_memcpy_gettimeofday(const struct function *r, size_t size, void *src, void *dst)
2558c2ecf20Sopenharmony_ci{
2568c2ecf20Sopenharmony_ci	struct timeval tv_start, tv_end, tv_diff;
2578c2ecf20Sopenharmony_ci	memcpy_t fn = r->fn.memcpy;
2588c2ecf20Sopenharmony_ci	int i;
2598c2ecf20Sopenharmony_ci
2608c2ecf20Sopenharmony_ci	memcpy_prefault(fn, size, src, dst);
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_ci	BUG_ON(gettimeofday(&tv_start, NULL));
2638c2ecf20Sopenharmony_ci	for (i = 0; i < nr_loops; ++i)
2648c2ecf20Sopenharmony_ci		fn(dst, src, size);
2658c2ecf20Sopenharmony_ci	BUG_ON(gettimeofday(&tv_end, NULL));
2668c2ecf20Sopenharmony_ci
2678c2ecf20Sopenharmony_ci	timersub(&tv_end, &tv_start, &tv_diff);
2688c2ecf20Sopenharmony_ci
2698c2ecf20Sopenharmony_ci	return (double)(((double)size * nr_loops) / timeval2double(&tv_diff));
2708c2ecf20Sopenharmony_ci}
2718c2ecf20Sopenharmony_ci
2728c2ecf20Sopenharmony_cistruct function memcpy_functions[] = {
2738c2ecf20Sopenharmony_ci	{ .name		= "default",
2748c2ecf20Sopenharmony_ci	  .desc		= "Default memcpy() provided by glibc",
2758c2ecf20Sopenharmony_ci	  .fn.memcpy	= memcpy },
2768c2ecf20Sopenharmony_ci
2778c2ecf20Sopenharmony_ci#ifdef HAVE_ARCH_X86_64_SUPPORT
2788c2ecf20Sopenharmony_ci# define MEMCPY_FN(_fn, _name, _desc) {.name = _name, .desc = _desc, .fn.memcpy = _fn},
2798c2ecf20Sopenharmony_ci# include "mem-memcpy-x86-64-asm-def.h"
2808c2ecf20Sopenharmony_ci# undef MEMCPY_FN
2818c2ecf20Sopenharmony_ci#endif
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_ci	{ .name = NULL, }
2848c2ecf20Sopenharmony_ci};
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_cistatic const char * const bench_mem_memcpy_usage[] = {
2878c2ecf20Sopenharmony_ci	"perf bench mem memcpy <options>",
2888c2ecf20Sopenharmony_ci	NULL
2898c2ecf20Sopenharmony_ci};
2908c2ecf20Sopenharmony_ci
2918c2ecf20Sopenharmony_ciint bench_mem_memcpy(int argc, const char **argv)
2928c2ecf20Sopenharmony_ci{
2938c2ecf20Sopenharmony_ci	struct bench_mem_info info = {
2948c2ecf20Sopenharmony_ci		.functions		= memcpy_functions,
2958c2ecf20Sopenharmony_ci		.do_cycles		= do_memcpy_cycles,
2968c2ecf20Sopenharmony_ci		.do_gettimeofday	= do_memcpy_gettimeofday,
2978c2ecf20Sopenharmony_ci		.usage			= bench_mem_memcpy_usage,
2988c2ecf20Sopenharmony_ci		.alloc_src              = true,
2998c2ecf20Sopenharmony_ci	};
3008c2ecf20Sopenharmony_ci
3018c2ecf20Sopenharmony_ci	return bench_mem_common(argc, argv, &info);
3028c2ecf20Sopenharmony_ci}
3038c2ecf20Sopenharmony_ci
3048c2ecf20Sopenharmony_cistatic u64 do_memset_cycles(const struct function *r, size_t size, void *src __maybe_unused, void *dst)
3058c2ecf20Sopenharmony_ci{
3068c2ecf20Sopenharmony_ci	u64 cycle_start = 0ULL, cycle_end = 0ULL;
3078c2ecf20Sopenharmony_ci	memset_t fn = r->fn.memset;
3088c2ecf20Sopenharmony_ci	int i;
3098c2ecf20Sopenharmony_ci
3108c2ecf20Sopenharmony_ci	/*
3118c2ecf20Sopenharmony_ci	 * We prefault the freshly allocated memory range here,
3128c2ecf20Sopenharmony_ci	 * to not measure page fault overhead:
3138c2ecf20Sopenharmony_ci	 */
3148c2ecf20Sopenharmony_ci	fn(dst, -1, size);
3158c2ecf20Sopenharmony_ci
3168c2ecf20Sopenharmony_ci	cycle_start = get_cycles();
3178c2ecf20Sopenharmony_ci	for (i = 0; i < nr_loops; ++i)
3188c2ecf20Sopenharmony_ci		fn(dst, i, size);
3198c2ecf20Sopenharmony_ci	cycle_end = get_cycles();
3208c2ecf20Sopenharmony_ci
3218c2ecf20Sopenharmony_ci	return cycle_end - cycle_start;
3228c2ecf20Sopenharmony_ci}
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_cistatic double do_memset_gettimeofday(const struct function *r, size_t size, void *src __maybe_unused, void *dst)
3258c2ecf20Sopenharmony_ci{
3268c2ecf20Sopenharmony_ci	struct timeval tv_start, tv_end, tv_diff;
3278c2ecf20Sopenharmony_ci	memset_t fn = r->fn.memset;
3288c2ecf20Sopenharmony_ci	int i;
3298c2ecf20Sopenharmony_ci
3308c2ecf20Sopenharmony_ci	/*
3318c2ecf20Sopenharmony_ci	 * We prefault the freshly allocated memory range here,
3328c2ecf20Sopenharmony_ci	 * to not measure page fault overhead:
3338c2ecf20Sopenharmony_ci	 */
3348c2ecf20Sopenharmony_ci	fn(dst, -1, size);
3358c2ecf20Sopenharmony_ci
3368c2ecf20Sopenharmony_ci	BUG_ON(gettimeofday(&tv_start, NULL));
3378c2ecf20Sopenharmony_ci	for (i = 0; i < nr_loops; ++i)
3388c2ecf20Sopenharmony_ci		fn(dst, i, size);
3398c2ecf20Sopenharmony_ci	BUG_ON(gettimeofday(&tv_end, NULL));
3408c2ecf20Sopenharmony_ci
3418c2ecf20Sopenharmony_ci	timersub(&tv_end, &tv_start, &tv_diff);
3428c2ecf20Sopenharmony_ci
3438c2ecf20Sopenharmony_ci	return (double)(((double)size * nr_loops) / timeval2double(&tv_diff));
3448c2ecf20Sopenharmony_ci}
3458c2ecf20Sopenharmony_ci
3468c2ecf20Sopenharmony_cistatic const char * const bench_mem_memset_usage[] = {
3478c2ecf20Sopenharmony_ci	"perf bench mem memset <options>",
3488c2ecf20Sopenharmony_ci	NULL
3498c2ecf20Sopenharmony_ci};
3508c2ecf20Sopenharmony_ci
3518c2ecf20Sopenharmony_cistatic const struct function memset_functions[] = {
3528c2ecf20Sopenharmony_ci	{ .name		= "default",
3538c2ecf20Sopenharmony_ci	  .desc		= "Default memset() provided by glibc",
3548c2ecf20Sopenharmony_ci	  .fn.memset	= memset },
3558c2ecf20Sopenharmony_ci
3568c2ecf20Sopenharmony_ci#ifdef HAVE_ARCH_X86_64_SUPPORT
3578c2ecf20Sopenharmony_ci# define MEMSET_FN(_fn, _name, _desc) { .name = _name, .desc = _desc, .fn.memset = _fn },
3588c2ecf20Sopenharmony_ci# include "mem-memset-x86-64-asm-def.h"
3598c2ecf20Sopenharmony_ci# undef MEMSET_FN
3608c2ecf20Sopenharmony_ci#endif
3618c2ecf20Sopenharmony_ci
3628c2ecf20Sopenharmony_ci	{ .name = NULL, }
3638c2ecf20Sopenharmony_ci};
3648c2ecf20Sopenharmony_ci
3658c2ecf20Sopenharmony_ciint bench_mem_memset(int argc, const char **argv)
3668c2ecf20Sopenharmony_ci{
3678c2ecf20Sopenharmony_ci	struct bench_mem_info info = {
3688c2ecf20Sopenharmony_ci		.functions		= memset_functions,
3698c2ecf20Sopenharmony_ci		.do_cycles		= do_memset_cycles,
3708c2ecf20Sopenharmony_ci		.do_gettimeofday	= do_memset_gettimeofday,
3718c2ecf20Sopenharmony_ci		.usage			= bench_mem_memset_usage,
3728c2ecf20Sopenharmony_ci	};
3738c2ecf20Sopenharmony_ci
3748c2ecf20Sopenharmony_ci	return bench_mem_common(argc, argv, &info);
3758c2ecf20Sopenharmony_ci}
376