diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2016-10-14 16:52:18 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2016-10-24 10:07:43 -0400 |
commit | 47b5757bac03c3387ccbe95507917b0f1dd6bb5b (patch) | |
tree | 3af3ab14d1b03761d6c04210e2a001fdceb26562 /tools | |
parent | e36b7821a985325dd7074de96deface5c9c6d700 (diff) |
perf bench mem: Move boilerplate memory allocation to the infrastructure
Instead of having all tests perform alloc/free, do it in the code that
calls the do_cycles() and do_gettimeofday() functions.
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Wang Nan <wangnan0@huawei.com>
Link: http://lkml.kernel.org/n/tip-lywj4mbdb1m9x1z9asivwuuy@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/bench/mem-functions.c | 77 |
1 files changed, 30 insertions, 47 deletions
diff --git a/tools/perf/bench/mem-functions.c b/tools/perf/bench/mem-functions.c index c684910e5a48..52504a83b5a1 100644 --- a/tools/perf/bench/mem-functions.c +++ b/tools/perf/bench/mem-functions.c | |||
@@ -106,9 +106,10 @@ static double timeval2double(struct timeval *ts) | |||
106 | 106 | ||
107 | struct bench_mem_info { | 107 | struct bench_mem_info { |
108 | const struct function *functions; | 108 | const struct function *functions; |
109 | u64 (*do_cycles)(const struct function *r, size_t size); | 109 | u64 (*do_cycles)(const struct function *r, size_t size, void *src, void *dst); |
110 | double (*do_gettimeofday)(const struct function *r, size_t size); | 110 | double (*do_gettimeofday)(const struct function *r, size_t size, void *src, void *dst); |
111 | const char *const *usage; | 111 | const char *const *usage; |
112 | bool alloc_src; | ||
112 | }; | 113 | }; |
113 | 114 | ||
114 | static void __bench_mem_function(struct bench_mem_info *info, int r_idx, size_t size, double size_total) | 115 | static void __bench_mem_function(struct bench_mem_info *info, int r_idx, size_t size, double size_total) |
@@ -116,16 +117,26 @@ static void __bench_mem_function(struct bench_mem_info *info, int r_idx, size_t | |||
116 | const struct function *r = &info->functions[r_idx]; | 117 | const struct function *r = &info->functions[r_idx]; |
117 | double result_bps = 0.0; | 118 | double result_bps = 0.0; |
118 | u64 result_cycles = 0; | 119 | u64 result_cycles = 0; |
120 | void *src = NULL, *dst = zalloc(size); | ||
119 | 121 | ||
120 | printf("# function '%s' (%s)\n", r->name, r->desc); | 122 | printf("# function '%s' (%s)\n", r->name, r->desc); |
121 | 123 | ||
124 | if (dst == NULL) | ||
125 | goto out_alloc_failed; | ||
126 | |||
127 | if (info->alloc_src) { | ||
128 | src = zalloc(size); | ||
129 | if (src == NULL) | ||
130 | goto out_alloc_failed; | ||
131 | } | ||
132 | |||
122 | if (bench_format == BENCH_FORMAT_DEFAULT) | 133 | if (bench_format == BENCH_FORMAT_DEFAULT) |
123 | printf("# Copying %s bytes ...\n\n", size_str); | 134 | printf("# Copying %s bytes ...\n\n", size_str); |
124 | 135 | ||
125 | if (use_cycles) { | 136 | if (use_cycles) { |
126 | result_cycles = info->do_cycles(r, size); | 137 | result_cycles = info->do_cycles(r, size, src, dst); |
127 | } else { | 138 | } else { |
128 | result_bps = info->do_gettimeofday(r, size); | 139 | result_bps = info->do_gettimeofday(r, size, src, dst); |
129 | } | 140 | } |
130 | 141 | ||
131 | switch (bench_format) { | 142 | switch (bench_format) { |
@@ -149,6 +160,14 @@ static void __bench_mem_function(struct bench_mem_info *info, int r_idx, size_t | |||
149 | BUG_ON(1); | 160 | BUG_ON(1); |
150 | break; | 161 | break; |
151 | } | 162 | } |
163 | |||
164 | out_free: | ||
165 | free(src); | ||
166 | free(dst); | ||
167 | return; | ||
168 | out_alloc_failed: | ||
169 | printf("# Memory allocation failed - maybe size (%s) is too large?\n", size_str); | ||
170 | goto out_free; | ||
152 | } | 171 | } |
153 | 172 | ||
154 | static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *info) | 173 | static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *info) |
@@ -201,28 +220,14 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info * | |||
201 | return 0; | 220 | return 0; |
202 | } | 221 | } |
203 | 222 | ||
204 | static void memcpy_alloc_mem(void **dst, void **src, size_t size) | 223 | static u64 do_memcpy_cycles(const struct function *r, size_t size, void *src, void *dst) |
205 | { | ||
206 | *dst = zalloc(size); | ||
207 | if (!*dst) | ||
208 | die("memory allocation failed - maybe size is too large?\n"); | ||
209 | |||
210 | *src = zalloc(size); | ||
211 | if (!*src) | ||
212 | die("memory allocation failed - maybe size is too large?\n"); | ||
213 | |||
214 | /* Make sure to always prefault zero pages even if MMAP_THRESH is crossed: */ | ||
215 | memset(*src, 0, size); | ||
216 | } | ||
217 | |||
218 | static u64 do_memcpy_cycles(const struct function *r, size_t size) | ||
219 | { | 224 | { |
220 | u64 cycle_start = 0ULL, cycle_end = 0ULL; | 225 | u64 cycle_start = 0ULL, cycle_end = 0ULL; |
221 | void *src = NULL, *dst = NULL; | ||
222 | memcpy_t fn = r->fn.memcpy; | 226 | memcpy_t fn = r->fn.memcpy; |
223 | int i; | 227 | int i; |
224 | 228 | ||
225 | memcpy_alloc_mem(&dst, &src, size); | 229 | /* Make sure to always prefault zero pages even if MMAP_THRESH is crossed: */ |
230 | memset(src, 0, size); | ||
226 | 231 | ||
227 | /* | 232 | /* |
228 | * We prefault the freshly allocated memory range here, | 233 | * We prefault the freshly allocated memory range here, |
@@ -235,20 +240,15 @@ static u64 do_memcpy_cycles(const struct function *r, size_t size) | |||
235 | fn(dst, src, size); | 240 | fn(dst, src, size); |
236 | cycle_end = get_cycles(); | 241 | cycle_end = get_cycles(); |
237 | 242 | ||
238 | free(src); | ||
239 | free(dst); | ||
240 | return cycle_end - cycle_start; | 243 | return cycle_end - cycle_start; |
241 | } | 244 | } |
242 | 245 | ||
243 | static double do_memcpy_gettimeofday(const struct function *r, size_t size) | 246 | static double do_memcpy_gettimeofday(const struct function *r, size_t size, void *src, void *dst) |
244 | { | 247 | { |
245 | struct timeval tv_start, tv_end, tv_diff; | 248 | struct timeval tv_start, tv_end, tv_diff; |
246 | memcpy_t fn = r->fn.memcpy; | 249 | memcpy_t fn = r->fn.memcpy; |
247 | void *src = NULL, *dst = NULL; | ||
248 | int i; | 250 | int i; |
249 | 251 | ||
250 | memcpy_alloc_mem(&dst, &src, size); | ||
251 | |||
252 | /* | 252 | /* |
253 | * We prefault the freshly allocated memory range here, | 253 | * We prefault the freshly allocated memory range here, |
254 | * to not measure page fault overhead: | 254 | * to not measure page fault overhead: |
@@ -262,9 +262,6 @@ static double do_memcpy_gettimeofday(const struct function *r, size_t size) | |||
262 | 262 | ||
263 | timersub(&tv_end, &tv_start, &tv_diff); | 263 | timersub(&tv_end, &tv_start, &tv_diff); |
264 | 264 | ||
265 | free(src); | ||
266 | free(dst); | ||
267 | |||
268 | return (double)(((double)size * nr_loops) / timeval2double(&tv_diff)); | 265 | return (double)(((double)size * nr_loops) / timeval2double(&tv_diff)); |
269 | } | 266 | } |
270 | 267 | ||
@@ -294,27 +291,18 @@ int bench_mem_memcpy(int argc, const char **argv, const char *prefix __maybe_unu | |||
294 | .do_cycles = do_memcpy_cycles, | 291 | .do_cycles = do_memcpy_cycles, |
295 | .do_gettimeofday = do_memcpy_gettimeofday, | 292 | .do_gettimeofday = do_memcpy_gettimeofday, |
296 | .usage = bench_mem_memcpy_usage, | 293 | .usage = bench_mem_memcpy_usage, |
294 | .alloc_src = true, | ||
297 | }; | 295 | }; |
298 | 296 | ||
299 | return bench_mem_common(argc, argv, &info); | 297 | return bench_mem_common(argc, argv, &info); |
300 | } | 298 | } |
301 | 299 | ||
302 | static void memset_alloc_mem(void **dst, size_t size) | 300 | static u64 do_memset_cycles(const struct function *r, size_t size, void *src __maybe_unused, void *dst) |
303 | { | ||
304 | *dst = zalloc(size); | ||
305 | if (!*dst) | ||
306 | die("memory allocation failed - maybe size is too large?\n"); | ||
307 | } | ||
308 | |||
309 | static u64 do_memset_cycles(const struct function *r, size_t size) | ||
310 | { | 301 | { |
311 | u64 cycle_start = 0ULL, cycle_end = 0ULL; | 302 | u64 cycle_start = 0ULL, cycle_end = 0ULL; |
312 | memset_t fn = r->fn.memset; | 303 | memset_t fn = r->fn.memset; |
313 | void *dst = NULL; | ||
314 | int i; | 304 | int i; |
315 | 305 | ||
316 | memset_alloc_mem(&dst, size); | ||
317 | |||
318 | /* | 306 | /* |
319 | * We prefault the freshly allocated memory range here, | 307 | * We prefault the freshly allocated memory range here, |
320 | * to not measure page fault overhead: | 308 | * to not measure page fault overhead: |
@@ -326,19 +314,15 @@ static u64 do_memset_cycles(const struct function *r, size_t size) | |||
326 | fn(dst, i, size); | 314 | fn(dst, i, size); |
327 | cycle_end = get_cycles(); | 315 | cycle_end = get_cycles(); |
328 | 316 | ||
329 | free(dst); | ||
330 | return cycle_end - cycle_start; | 317 | return cycle_end - cycle_start; |
331 | } | 318 | } |
332 | 319 | ||
333 | static double do_memset_gettimeofday(const struct function *r, size_t size) | 320 | static double do_memset_gettimeofday(const struct function *r, size_t size, void *src __maybe_unused, void *dst) |
334 | { | 321 | { |
335 | struct timeval tv_start, tv_end, tv_diff; | 322 | struct timeval tv_start, tv_end, tv_diff; |
336 | memset_t fn = r->fn.memset; | 323 | memset_t fn = r->fn.memset; |
337 | void *dst = NULL; | ||
338 | int i; | 324 | int i; |
339 | 325 | ||
340 | memset_alloc_mem(&dst, size); | ||
341 | |||
342 | /* | 326 | /* |
343 | * We prefault the freshly allocated memory range here, | 327 | * We prefault the freshly allocated memory range here, |
344 | * to not measure page fault overhead: | 328 | * to not measure page fault overhead: |
@@ -352,7 +336,6 @@ static double do_memset_gettimeofday(const struct function *r, size_t size) | |||
352 | 336 | ||
353 | timersub(&tv_end, &tv_start, &tv_diff); | 337 | timersub(&tv_end, &tv_start, &tv_diff); |
354 | 338 | ||
355 | free(dst); | ||
356 | return (double)(((double)size * nr_loops) / timeval2double(&tv_diff)); | 339 | return (double)(((double)size * nr_loops) / timeval2double(&tv_diff)); |
357 | } | 340 | } |
358 | 341 | ||