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