12 #include "../util/util.h" 13 #include <subcmd/parse-options.h> 14 #include "../util/header.h" 15 #include "../util/cloexec.h" 16 #include "../util/string2.h" 26 #include <linux/time64.h> 37 OPT_STRING(
's',
"size", &
size_str,
"1MB",
38 "Specify the size of the memory buffers. " 39 "Available units: B, KB, MB, GB and TB (case insensitive)"),
42 "Specify the function to run, \"all\" runs all available functions, \"help\" lists them"),
44 OPT_INTEGER(
'l',
"nr_loops", &
nr_loops,
45 "Specify the number of loops to run. (default: 1)"),
48 "Use a cycles event instead of gettimeofday() to measure performance"),
53 typedef void *(*memcpy_t)(
void *,
const void *, size_t);
54 typedef void *(*memset_t)(
void *, int, size_t);
66 .type = PERF_TYPE_HARDWARE,
67 .config = PERF_COUNT_HW_CPU_CYCLES
75 pr_debug(
"No CONFIG_PERF_EVENTS=y kernel support configured?\n");
88 BUG_ON(ret !=
sizeof(u64));
95 return (
double)ts->tv_sec + (double)ts->tv_usec / (
double)USEC_PER_SEC;
98 #define print_bps(x) do { \ 100 printf(" %14lf bytes/sec\n", x); \ 101 else if (x < K * K) \ 102 printf(" %14lfd KB/sec\n", x / K); \ 103 else if (x < K * K * K) \ 104 printf(" %14lf MB/sec\n", x / K / K); \ 106 printf(" %14lf GB/sec\n", x / K / K / K); \ 111 u64 (*do_cycles)(
const struct function *r,
size_t size,
void *src,
void *dst);
112 double (*do_gettimeofday)(
const struct function *r,
size_t size,
void *src,
void *dst);
120 double result_bps = 0.0;
121 u64 result_cycles = 0;
122 void *src = NULL, *dst =
zalloc(size);
124 printf(
"# function '%s' (%s)\n", r->
name, r->
desc);
127 goto out_alloc_failed;
132 goto out_alloc_failed;
136 printf(
"# Copying %s bytes ...\n\n",
size_str);
139 result_cycles = info->
do_cycles(r, size, src, dst);
147 printf(
" %14lf cycles/byte\n", (
double)result_cycles/size_total);
155 printf(
"%lf\n", (
double)result_cycles/size_total);
157 printf(
"%lf\n", result_bps);
171 printf(
"# Memory allocation failed - maybe size (%s) is too large?\n",
size_str);
181 argc = parse_options(argc, argv,
options, info->
usage, 0);
186 fprintf(stderr,
"Failed to open cycles counter\n");
192 size_total = (double)size *
nr_loops;
194 if ((s64)size <= 0) {
195 fprintf(stderr,
"Invalid size:%s\n",
size_str);
212 printf(
"Available functions:\n");
214 printf(
"\t%s ... %s\n",
227 u64 cycle_start = 0ULL, cycle_end = 0ULL;
245 return cycle_end - cycle_start;
250 struct timeval tv_start, tv_end, tv_diff;
260 BUG_ON(gettimeofday(&tv_start, NULL));
263 BUG_ON(gettimeofday(&tv_end, NULL));
265 timersub(&tv_end, &tv_start, &tv_diff);
267 return (
double)(((double)size * nr_loops) /
timeval2double(&tv_diff));
272 .desc =
"Default memcpy() provided by glibc",
275 #ifdef HAVE_ARCH_X86_64_SUPPORT 276 # define MEMCPY_FN(_fn, _name, _desc) {.name = _name, .desc = _desc, .fn.memcpy = _fn}, 285 "perf bench mem memcpy <options>",
304 u64 cycle_start = 0ULL, cycle_end = 0ULL;
319 return cycle_end - cycle_start;
324 struct timeval tv_start, tv_end, tv_diff;
334 BUG_ON(gettimeofday(&tv_start, NULL));
337 BUG_ON(gettimeofday(&tv_end, NULL));
339 timersub(&tv_end, &tv_start, &tv_diff);
341 return (
double)(((double)size * nr_loops) /
timeval2double(&tv_diff));
345 "perf bench mem memset <options>",
351 .desc =
"Default memset() provided by glibc",
354 #ifdef HAVE_ARCH_X86_64_SUPPORT 355 # define MEMSET_FN(_fn, _name, _desc) { .name = _name, .desc = _desc, .fn.memset = _fn },
static u64 do_memset_cycles(const struct function *r, size_t size, void *src __maybe_unused, void *dst)
const char *const * usage
int bench_mem_memset(int argc, const char **argv)
static int sys_perf_event_open(struct perf_event_attr *attr, pid_t pid, int cpu, int group_fd, unsigned long flags)
static double do_memcpy_gettimeofday(const struct function *r, size_t size, void *src, void *dst)
s64 perf_atoll(const char *str)
#define BENCH_FORMAT_DEFAULT
static double timeval2double(struct timeval *ts)
static const char *const bench_mem_memset_usage[]
static const struct function memset_functions[]
struct function memcpy_functions[]
#define pr_debug(fmt,...)
static u64 get_cycles(void)
static u64 do_memcpy_cycles(const struct function *r, size_t size, void *src, void *dst)
const struct function * functions
static int init_cycles(void)
int bench_mem_memcpy(int argc, const char **argv)
static double do_memset_gettimeofday(const struct function *r, size_t size, void *src __maybe_unused, void *dst)
void *(* memcpy_t)(void *, const void *, size_t)
unsigned long perf_event_open_cloexec_flag(void)
double(* do_gettimeofday)(const struct function *r, size_t size, void *src, void *dst)
static const char * size_str
static const char *const bench_mem_memcpy_usage[]
static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *info)
static const char * function_str
#define BENCH_FORMAT_SIMPLE
static void __bench_mem_function(struct bench_mem_info *info, int r_idx, size_t size, double size_total)
void *(* memset_t)(void *, int, size_t)
u64(* do_cycles)(const struct function *r, size_t size, void *src, void *dst)
static struct perf_event_attr cycle_attr
void static void * zalloc(size_t size)