10 #include "../util/util.h"
11 #include "../util/parse-options.h"
12 #include "../util/header.h"
24 static const char *length_str =
"1MB";
25 static const char *
routine =
"default";
26 static int iterations = 1;
27 static bool use_cycle;
29 static bool only_prefault;
30 static bool no_prefault;
34 "Specify length of memory to set. "
35 "Available units: B, KB, MB, GB and TB (upper and lower)"),
37 "Specify routine to set"),
39 "repeat memset() invocation this number of times"),
41 "Use cycles event instead of gettimeofday() for measuring"),
43 "Show only the result with page faults before memset()"),
45 "Show only the result without page faults before memset()"),
59 "Default memset() provided by glibc",
63 #define MEMSET_FN(fn, name, desc) { name, desc, fn },
74 static const char *
const bench_mem_memset_usage[] = {
75 "perf bench mem memset <options>",
84 static void init_cycle(
void)
88 if (cycle_fd < 0 && errno ==
ENOSYS)
89 die(
"No CONFIG_PERF_EVENTS=y kernel support configured?\n");
94 static u64 get_cycle(
void)
99 ret =
read(cycle_fd, &clk,
sizeof(
u64));
105 static double timeval2double(
struct timeval *
ts)
107 return (
double)ts->
tv_sec +
108 (double)ts->
tv_usec / (
double)1000000;
111 static void alloc_mem(
void **
dst,
size_t length)
115 die(
"memory allocation failed - maybe length is too large?\n");
118 static u64 do_memset_cycle(
memset_t fn,
size_t len,
bool prefault)
120 u64 cycle_start = 0ULL, cycle_end = 0ULL;
124 alloc_mem(&dst, len);
129 cycle_start = get_cycle();
130 for (i = 0; i < iterations; ++
i)
132 cycle_end = get_cycle();
135 return cycle_end - cycle_start;
138 static double do_memset_gettimeofday(
memset_t fn,
size_t len,
bool prefault)
140 struct timeval tv_start, tv_end, tv_diff;
144 alloc_mem(&dst, len);
150 for (i = 0; i < iterations; ++
i)
154 timersub(&tv_end, &tv_start, &tv_diff);
157 return (
double)((double)len / timeval2double(&tv_diff));
160 #define pf (no_prefault ? 0 : 1)
162 #define print_bps(x) do { \
164 printf(" %14lf B/Sec", x); \
165 else if (x < K * K) \
166 printf(" %14lfd KB/Sec", x / K); \
167 else if (x < K * K * K) \
168 printf(" %14lf MB/Sec", x / K / K); \
170 printf(" %14lf GB/Sec", x / K / K / K); \
178 double result_bps[2];
182 bench_mem_memset_usage, 0);
189 result_cycle[0] = result_cycle[1] = 0ULL;
190 result_bps[0] = result_bps[1] = 0.0;
193 fprintf(stderr,
"Invalid length:%s\n", length_str);
198 if (only_prefault && no_prefault)
199 only_prefault = no_prefault =
false;
201 for (i = 0; routines[
i].
name; i++) {
205 if (!routines[i].
name) {
207 printf(
"Available routines...\n");
208 for (i = 0; routines[
i].
name; i++) {
210 routines[i].name, routines[i].
desc);
216 printf(
"# Copying %s Bytes ...\n\n", length_str);
218 if (!only_prefault && !no_prefault) {
222 do_memset_cycle(routines[i].fn, len,
false);
224 do_memset_cycle(routines[i].fn, len,
true);
227 do_memset_gettimeofday(routines[i].fn,
230 do_memset_gettimeofday(routines[i].fn,
236 do_memset_cycle(routines[i].fn,
240 do_memset_gettimeofday(routines[i].fn,
247 if (!only_prefault && !no_prefault) {
249 printf(
" %14lf Cycle/Byte\n",
250 (
double)result_cycle[0]
252 printf(
" %14lf Cycle/Byte (with prefault)\n ",
253 (
double)result_cycle[1]
259 printf(
" (with prefault)\n");
263 printf(
" %14lf Cycle/Byte",
264 (
double)result_cycle[
pf]
269 printf(
"%s\n", only_prefault ?
" (with prefault)" :
"");
273 if (!only_prefault && !no_prefault) {
276 (
double)result_cycle[0] / (
double)len,
277 (
double)result_cycle[1] / (
double)len);
280 result_bps[0], result_bps[1]);
284 printf(
"%lf\n", (
double)result_cycle[
pf]