perf bench: Misc improvements
cover perf bench: Misc improvements
So I'm working towards adding more 'perf bench' benchmarks and found a few rough edges - fixed by the series below.
Thanks,
Ingo
Ingo Molnar (14):
perf/bench: Improve the 'perf bench mem memcpy' code readability perf/bench: Default to all routines in 'perf bench mem' perf/bench: Eliminate unused argument from bench_mem_common() perf/bench: Rename 'mem-memcpy.c' => 'mem-functions.c' perf/bench: Remove the prefaulting complication from 'perf bench mem mem*' perf/bench: List output formatting options on 'perf bench -h' perf/bench/mem: Change 'cycle' to 'cycles'
perf/bench/mem: Rename 'routine' to 'routine_str' perf/bench/mem: Fix 'length' vs. 'size' naming confusion perf/bench/mem: Improve user visible strings
perf/bench/mem: Reorganize the code a bit
perf/bench: Harmonize all the -l/--nr_loops options perf/bench/mem: Rename 'routine' to 'function'
perf/bench: Run benchmarks, don't test them
tools/perf/bench/Build | 2 +- tools/perf/bench/mem-functions.c | 379 +++++++++++++++++++++++++++++++++++++++++++++++++ tools/perf/bench/mem-memcpy.c | 434 --------------------------------------------------------- tools/perf/bench/numa.c | 4 +- tools/perf/bench/sched-messaging.c | 10 +- tools/perf/builtin-bench.c | 14 +- 6 files changed, 394 insertions(+), 449 deletions(-) create mode 100644 tools/perf/bench/mem-functions.c delete mode 100644 tools/perf/bench/mem-memcpy.c
Signature · 1 line
2.1.4
PATCH 1/14 perf/bench: Improve the 'perf bench mem memcpy' code readability
- improve the readability of initializations
- fix unnecessary double negations
- fix ugly line breaks
- fix other small details
--- tools/perf/bench/mem-memcpy.c | 101 ++++++++++++++++++++++++++++---------------------------------- 1 file changed, 45 insertions(+), 56 deletions(-)
tools/perf/bench/mem-memcpy.c +45 -56
@@ -1,7 +1,7 @@/* * mem-memcpy.c * -* memcpy: Simple memory copy in various ways +* Simple memcpy() and memset() benchmarks * * Written by Hitoshi Mitake <[email protected]> */
@@ -61,20 +61,17 @@ struct routine { };struct routine memcpy_routines[] = { - { .name ="default" , - .desc ="Default memcpy() provided by glibc" , - .fn.memcpy = memcpy }, -#ifdef HAVE_ARCH_X86_64_SUPPORT - -#define MEMCPY_FN(_fn, _name, _desc) {.name = _name, .desc = _desc, .fn.memcpy = _fn}, -#include "mem-memcpy-x86-64-asm-def.h" -#undef MEMCPY_FN + { .name ="default" , + .desc ="Default memcpy() provided by glibc" , + .fn.memcpy = memcpy }, +#ifdef HAVE_ARCH_X86_64_SUPPORT +# define MEMCPY_FN(_fn, _name, _desc) {.name = _name, .desc = _desc, .fn.memcpy = _fn}, +# include "mem-memcpy-x86-64-asm-def.h" +# undef MEMCPY_FN #endif - {NULL , -NULL , - {NULL } } + {NULL , } };static const char *const bench_mem_memcpy_usage[] = {
@@ -89,8 +86,7 @@ static struct perf_event_attr cycle_attr = {static void init_cycle (void ) { - cycle_fd =sys_perf_event_open (&cycle_attr,getpid (),-1 ,-1 , -perf_event_open_cloexec_flag ()); + cycle_fd =sys_perf_event_open (&cycle_attr,getpid (),-1 ,-1 ,perf_event_open_cloexec_flag ());if (cycle_fd <0 && errno ==ENOSYS )die ("No CONFIG_PERF_EVENTS=y kernel support configured?\n" );
@@ -111,12 +107,9 @@ static u64 get_cycle(void)static double timeval2double (struct timeval *ts) { -return (double )ts->tv_sec + - (double )ts->tv_usec / (double )1000000 ; +return (double )ts->tv_sec + (double )ts->tv_usec / (double )1000000 ; } -#define pf (no_prefault ? 0 : 1) -#define print_bps (x) do { \ if (x < K) \ printf(" %14lf B/Sec", x); \
@@ -140,6 +133,7 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t lconst struct routine *r = &info->routines[r_idx];double result_bps[2 ];u64 result_cycle[2 ]; +int prefault = no_prefault ?0 :1 ; result_cycle[0 ] = result_cycle[1 ] =0ULL ; result_bps[0 ] = result_bps[1 ] =0.0 ;
@@ -149,8 +143,8 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t lif (bench_format ==BENCH_FORMAT_DEFAULT )printf ("# Copying %s Bytes ...\n\n" , length_str); -if (!only_prefault && !no_prefault) { -/* show both of results */ +if (!only_prefault && prefault) { +/* Show both results: */ if (use_cycle) { result_cycle[0 ] = info->do_cycle (r, len, false); result_cycle[1 ] = info->do_cycle (r, len, true);
@@ -160,14 +154,14 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l } }else {if (use_cycle) - result_cycle[pf] = info->do_cycle (r, len, only_prefault); + result_cycle[prefault] = info->do_cycle (r, len, only_prefault);else - result_bps[pf] = info->do_gettimeofday (r, len, only_prefault); + result_bps[prefault] = info->do_gettimeofday (r, len, only_prefault); }switch (bench_format) {case BENCH_FORMAT_DEFAULT : -if (!only_prefault && !no_prefault) { +if (!only_prefault && prefault) {if (use_cycle) {printf (" %14lf Cycle/Byte\n" , (double)result_cycle[0]
@@ -184,16 +178,16 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l }else {if (use_cycle) {printf (" %14lf Cycle/Byte" , - (double )result_cycle[pf] + (double )result_cycle[prefault] / totallen); }else -print_bps (result_bps[pf]); +print_bps (result_bps[prefault]);printf ("%s\n" , only_prefault ?" (with prefault)" :"" ); }break ;case BENCH_FORMAT_SIMPLE : -if (!only_prefault && !no_prefault) { +if (!only_prefault && prefault) {if (use_cycle) { printf("%lf %lf\n", (double)result_cycle[0] / totallen,
@@ -204,14 +198,14 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l } }else {if (use_cycle) { -printf ("%lf\n" , (double )result_cycle[pf] +printf ("%lf\n" , (double )result_cycle[prefault] / totallen); }else -printf ("%lf\n" , result_bps[pf]); +printf ("%lf\n" , result_bps[prefault]); }break ;default : -/* reaching this means there's some disaster: */ +/* Reaching this means there's some disaster: */ die ("unknown format: %d\n" , bench_format);break ; }
@@ -225,8 +219,7 @@ static int bench_mem_common(int argc, const char **argv,size_t len;double totallen; - argc =parse_options (argc, argv, options, - info->usage,0 ); + argc =parse_options (argc, argv, options, info->usage,0 );if (no_prefault && only_prefault) {fprintf (stderr,"Invalid options: -o and -n are mutually exclusive\n" );
@@ -244,7 +237,7 @@ static int bench_mem_common(int argc, const char **argv,return 1 ; } -/* same to without specifying either of prefault and no-prefault */ +/* Same as without specifying either of prefault and no-prefault: */ if (only_prefault && no_prefault) only_prefault = no_prefault = false;
@@ -282,7 +275,8 @@ static void memcpy_alloc_mem(void **dst, void **src, size_t length) *src =zalloc (length);if (!*src)die ("memory allocation failed - maybe length is too large?\n" ); -/* Make sure to always replace the zero pages even if MMAP_THRESH is crossed */ + +/* Make sure to always prefault zero pages even if MMAP_THRESH is crossed: */ memset (*src,0 , length); }
@@ -308,8 +302,7 @@ static u64 do_memcpy_cycle(const struct routine *r, size_t len, bool prefault)return cycle_end - cycle_start; } -static double do_memcpy_gettimeofday (const struct routine *r,size_t len, -bool prefault) +static double do_memcpy_gettimeofday (const struct routine *r,size_t len,bool prefault) {struct timeval tv_start, tv_end, tv_diff;memcpy_t fn = r->fn.memcpy;
@@ -337,10 +330,10 @@ int bench_mem_memcpy(int argc, const char **argv, const char *prefix __maybe_unused) {struct bench_mem_info info = { - .routines = memcpy_routines, - .do_cycle = do_memcpy_cycle, - .do_gettimeofday = do_memcpy_gettimeofday, - .usage = bench_mem_memcpy_usage, + .routines = memcpy_routines, + .do_cycle = do_memcpy_cycle, + .do_gettimeofday = do_memcpy_gettimeofday, + .usage = bench_mem_memcpy_usage, };return bench_mem_common (argc, argv, prefix, &info);
@@ -404,30 +397,26 @@ static const char * const bench_mem_memset_usage[] = { };static const struct routine memset_routines[] = { - { .name ="default" , - .desc ="Default memset() provided by glibc" , - .fn.memset = memset }, -#ifdef HAVE_ARCH_X86_64_SUPPORT - -#define MEMSET_FN(_fn, _name, _desc) { .name = _name, .desc = _desc, .fn.memset = _fn }, -#include "mem-memset-x86-64-asm-def.h" -#undef MEMSET_FN + { .name ="default" , + .desc ="Default memset() provided by glibc" , + .fn.memset = memset }, +#ifdef HAVE_ARCH_X86_64_SUPPORT +# define MEMSET_FN(_fn, _name, _desc) { .name = _name, .desc = _desc, .fn.memset = _fn }, +# include "mem-memset-x86-64-asm-def.h" +# undef MEMSET_FN #endif - { .name =NULL , - .desc =NULL , - .fn.memset =NULL } + {NULL , } }; -int bench_mem_memset (int argc,const char **argv, -const char *prefix__maybe_unused ) +int bench_mem_memset (int argc,const char **argv,const char *prefix__maybe_unused ) {struct bench_mem_info info = { - .routines = memset_routines, - .do_cycle = do_memset_cycle, - .do_gettimeofday = do_memset_gettimeofday, - .usage = bench_mem_memset_usage, + .routines = memset_routines, + .do_cycle = do_memset_cycle, + .do_gettimeofday = do_memset_gettimeofday, + .usage = bench_mem_memset_usage, };return bench_mem_common (argc, argv, prefix, &info);
Signature · 1 line
2.1.4
tip-bot for Ingo Molnar
merge bot[tip:perf/core] perf bench: Improve the 'perf bench mem memcpy' code readability
perf bench: Improve the 'perf bench mem memcpy' code readability
Commit-ID: 13839ec495a31844d66d487f740c07771c60a0d0 Gitweb: http://git.kernel.org/tip/13839ec495a31844d66d487f740c07771c60a0d0 Author: Ingo Molnar <[email protected]> AuthorDate: Mon, 19 Oct 2015 10:04:17 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Mon, 19 Oct 2015 15:05:00 -0300
perf bench: Improve the 'perf bench mem memcpy' code readability
- improve the readability of initializations
- fix unnecessary double negations
- fix ugly line breaks
- fix other small details
--- tools/perf/bench/mem-memcpy.c | 101 +++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 56 deletions(-)
tools/perf/bench/mem-memcpy.c +45 -56
@@ -1,7 +1,7 @@/* * mem-memcpy.c * -* memcpy: Simple memory copy in various ways +* Simple memcpy() and memset() benchmarks * * Written by Hitoshi Mitake <[email protected]> */
@@ -61,20 +61,17 @@ struct routine { };struct routine memcpy_routines[] = { - { .name ="default" , - .desc ="Default memcpy() provided by glibc" , - .fn.memcpy = memcpy }, -#ifdef HAVE_ARCH_X86_64_SUPPORT - -#define MEMCPY_FN(_fn, _name, _desc) {.name = _name, .desc = _desc, .fn.memcpy = _fn}, -#include "mem-memcpy-x86-64-asm-def.h" -#undef MEMCPY_FN + { .name ="default" , + .desc ="Default memcpy() provided by glibc" , + .fn.memcpy = memcpy }, +#ifdef HAVE_ARCH_X86_64_SUPPORT +# define MEMCPY_FN(_fn, _name, _desc) {.name = _name, .desc = _desc, .fn.memcpy = _fn}, +# include "mem-memcpy-x86-64-asm-def.h" +# undef MEMCPY_FN #endif - {NULL , -NULL , - {NULL } } + {NULL , } };static const char *const bench_mem_memcpy_usage[] = {
@@ -89,8 +86,7 @@ static struct perf_event_attr cycle_attr = {static void init_cycle (void ) { - cycle_fd =sys_perf_event_open (&cycle_attr,getpid (),-1 ,-1 , -perf_event_open_cloexec_flag ()); + cycle_fd =sys_perf_event_open (&cycle_attr,getpid (),-1 ,-1 ,perf_event_open_cloexec_flag ());if (cycle_fd <0 && errno ==ENOSYS )die ("No CONFIG_PERF_EVENTS=y kernel support configured?\n" );
@@ -111,12 +107,9 @@ static u64 get_cycle(void)static double timeval2double (struct timeval *ts) { -return (double )ts->tv_sec + - (double )ts->tv_usec / (double )1000000 ; +return (double )ts->tv_sec + (double )ts->tv_usec / (double )1000000 ; } -#define pf (no_prefault ? 0 : 1) -#define print_bps (x) do { \ if (x < K) \ printf(" %14lf B/Sec", x); \
@@ -140,6 +133,7 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t lconst struct routine *r = &info->routines[r_idx];double result_bps[2 ];u64 result_cycle[2 ]; +int prefault = no_prefault ?0 :1 ; result_cycle[0 ] = result_cycle[1 ] =0ULL ; result_bps[0 ] = result_bps[1 ] =0.0 ;
@@ -149,8 +143,8 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t lif (bench_format ==BENCH_FORMAT_DEFAULT )printf ("# Copying %s Bytes ...\n\n" , length_str); -if (!only_prefault && !no_prefault) { -/* show both of results */ +if (!only_prefault && prefault) { +/* Show both results: */ if (use_cycle) { result_cycle[0 ] = info->do_cycle (r, len, false); result_cycle[1 ] = info->do_cycle (r, len, true);
@@ -160,14 +154,14 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l } }else {if (use_cycle) - result_cycle[pf] = info->do_cycle (r, len, only_prefault); + result_cycle[prefault] = info->do_cycle (r, len, only_prefault);else - result_bps[pf] = info->do_gettimeofday (r, len, only_prefault); + result_bps[prefault] = info->do_gettimeofday (r, len, only_prefault); }switch (bench_format) {case BENCH_FORMAT_DEFAULT : -if (!only_prefault && !no_prefault) { +if (!only_prefault && prefault) {if (use_cycle) {printf (" %14lf Cycle/Byte\n" , (double)result_cycle[0]
@@ -184,16 +178,16 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l }else {if (use_cycle) {printf (" %14lf Cycle/Byte" , - (double )result_cycle[pf] + (double )result_cycle[prefault] / totallen); }else -print_bps (result_bps[pf]); +print_bps (result_bps[prefault]);printf ("%s\n" , only_prefault ?" (with prefault)" :"" ); }break ;case BENCH_FORMAT_SIMPLE : -if (!only_prefault && !no_prefault) { +if (!only_prefault && prefault) {if (use_cycle) { printf("%lf %lf\n", (double)result_cycle[0] / totallen,
@@ -204,14 +198,14 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l } }else {if (use_cycle) { -printf ("%lf\n" , (double )result_cycle[pf] +printf ("%lf\n" , (double )result_cycle[prefault] / totallen); }else -printf ("%lf\n" , result_bps[pf]); +printf ("%lf\n" , result_bps[prefault]); }break ;default : -/* reaching this means there's some disaster: */ +/* Reaching this means there's some disaster: */ die ("unknown format: %d\n" , bench_format);break ; }
@@ -225,8 +219,7 @@ static int bench_mem_common(int argc, const char **argv,size_t len;double totallen; - argc =parse_options (argc, argv, options, - info->usage,0 ); + argc =parse_options (argc, argv, options, info->usage,0 );if (no_prefault && only_prefault) {fprintf (stderr,"Invalid options: -o and -n are mutually exclusive\n" );
@@ -244,7 +237,7 @@ static int bench_mem_common(int argc, const char **argv,return 1 ; } -/* same to without specifying either of prefault and no-prefault */ +/* Same as without specifying either of prefault and no-prefault: */ if (only_prefault && no_prefault) only_prefault = no_prefault = false;
@@ -282,7 +275,8 @@ static void memcpy_alloc_mem(void **dst, void **src, size_t length) *src =zalloc (length);if (!*src)die ("memory allocation failed - maybe length is too large?\n" ); -/* Make sure to always replace the zero pages even if MMAP_THRESH is crossed */ + +/* Make sure to always prefault zero pages even if MMAP_THRESH is crossed: */ memset (*src,0 , length); }
@@ -308,8 +302,7 @@ static u64 do_memcpy_cycle(const struct routine *r, size_t len, bool prefault)return cycle_end - cycle_start; } -static double do_memcpy_gettimeofday (const struct routine *r,size_t len, -bool prefault) +static double do_memcpy_gettimeofday (const struct routine *r,size_t len,bool prefault) {struct timeval tv_start, tv_end, tv_diff;memcpy_t fn = r->fn.memcpy;
@@ -337,10 +330,10 @@ int bench_mem_memcpy(int argc, const char **argv, const char *prefix __maybe_unused) {struct bench_mem_info info = { - .routines = memcpy_routines, - .do_cycle = do_memcpy_cycle, - .do_gettimeofday = do_memcpy_gettimeofday, - .usage = bench_mem_memcpy_usage, + .routines = memcpy_routines, + .do_cycle = do_memcpy_cycle, + .do_gettimeofday = do_memcpy_gettimeofday, + .usage = bench_mem_memcpy_usage, };return bench_mem_common (argc, argv, prefix, &info);
@@ -404,30 +397,26 @@ static const char * const bench_mem_memset_usage[] = { };static const struct routine memset_routines[] = { - { .name ="default" , - .desc ="Default memset() provided by glibc" , - .fn.memset = memset }, -#ifdef HAVE_ARCH_X86_64_SUPPORT - -#define MEMSET_FN(_fn, _name, _desc) { .name = _name, .desc = _desc, .fn.memset = _fn }, -#include "mem-memset-x86-64-asm-def.h" -#undef MEMSET_FN + { .name ="default" , + .desc ="Default memset() provided by glibc" , + .fn.memset = memset }, +#ifdef HAVE_ARCH_X86_64_SUPPORT +# define MEMSET_FN(_fn, _name, _desc) { .name = _name, .desc = _desc, .fn.memset = _fn }, +# include "mem-memset-x86-64-asm-def.h" +# undef MEMSET_FN #endif - { .name =NULL , - .desc =NULL , - .fn.memset =NULL } + {NULL , } }; -int bench_mem_memset (int argc,const char **argv, -const char *prefix__maybe_unused ) +int bench_mem_memset (int argc,const char **argv,const char *prefix__maybe_unused ) {struct bench_mem_info info = { - .routines = memset_routines, - .do_cycle = do_memset_cycle, - .do_gettimeofday = do_memset_gettimeofday, - .usage = bench_mem_memset_usage, + .routines = memset_routines, + .do_cycle = do_memset_cycle, + .do_gettimeofday = do_memset_gettimeofday, + .usage = bench_mem_memset_usage, };return bench_mem_common (argc, argv, prefix, &info);
PATCH 2/14 perf/bench: Default to all routines in 'perf bench mem'
In reply to Ingo MolnarSo few people know that the --routine option to 'perf bench memcpy/memset' exists, and would not know that it's capable of testing the kernel's memcpy/memset implementations.
Furthermore, 'perf bench mem all' will not run all routines:
vega:~> perf bench mem all
# Running mem/memcpy benchmark...
Routine default (Default memcpy() provided by glibc) # Copying 1MB Bytes ...
894.454383 MB/Sec
3.844734 GB/Sec (with prefault)
# Running mem/memset benchmark...
Routine default (Default memset() provided by glibc) # Copying 1MB Bytes ...
1.220703 GB/Sec
9.042245 GB/Sec (with prefault)
Because misleadingly the 'all' refers to 'all sub-benchmarks', not 'all sub-benchmarks and routines'.
Fix all this by making the memcpy/memset routine to default to 'all', which results in all the benchmarks being run:
triton:~> perf bench mem all # Running mem/memcpy benchmark... Routine default (Default memcpy() provided by glibc) # Copying 1MB Bytes ... 1.448906 GB/Sec 4.957170 GB/Sec (with prefault) Routine x86-64-unrolled (unrolled memcpy() in arch/x86/lib/memcpy_64.S) # Copying 1MB Bytes ... 1.614153 GB/Sec 4.379204 GB/Sec (with prefault) Routine x86-64-movsq (movsq-based memcpy() in arch/x86/lib/memcpy_64.S) # Copying 1MB Bytes ... 1.570036 GB/Sec 4.264465 GB/Sec (with prefault) Routine x86-64-movsb (movsb-based memcpy() in arch/x86/lib/memcpy_64.S) # Copying 1MB Bytes ... 1.788576 GB/Sec 6.554111 GB/Sec (with prefault) # Running mem/memset benchmark... Routine default (Default memset() provided by glibc) # Copying 1MB Bytes ... 2.082223 GB/Sec 9.126752 GB/Sec (with prefault) Routine x86-64-unrolled (unrolled memset() in arch/x86/lib/memset_64.S) # Copying 1MB Bytes ... 5.710892 GB/Sec 8.346688 GB/Sec (with prefault) Routine x86-64-stosq (movsq-based memset() in arch/x86/lib/memset_64.S) # Copying 1MB Bytes ... 9.765625 GB/Sec 12.520032 GB/Sec (with prefault) Routine x86-64-stosb (movsb-based memset() in arch/x86/lib/memset_64.S) # Copying 1MB Bytes ... 9.668936 GB/Sec 12.682630 GB/Sec (with prefault)
--- tools/perf/bench/mem-memcpy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/perf/bench/mem-memcpy.c +2 -2
@@ -24,7 +24,7 @@#define K 1024static const char *length_str ="1MB" ; -static const char *routine ="default" ; +static const char *routine ="all" ;static int iterations =1 ;static bool use_cycle;static int cycle_fd;
@@ -35,7 +35,7 @@ static const struct option options[] = {OPT_STRING ('l' ,"length" , &length_str,"1MB" ,"Specify length of memory to copy. " "Available units: B, KB, MB, GB and TB (upper and lower)" ), -OPT_STRING ('r' ,"routine" , &routine,"default" , +OPT_STRING ('r' ,"routine" , &routine,"all" ,"Specify routine to copy, \"all\" runs all available routines" ),OPT_INTEGER ('i' ,"iterations" , &iterations, "repeat memcpy() invocation this number of times"),
Signature · 1 line
2.1.4
Re: [PATCH 02/14] perf/bench: Default to all routines in 'perf bench mem'
Quoted 11 lines · Ingo Molnar
triton:~> perf bench mem all
# Running mem/memcpy benchmark...
Routine default (Default memcpy() provided by glibc)
4.957170 GB/Sec (with prefault)
Routine x86-64-unrolled (unrolled memcpy() in arch/x86/lib/memcpy_64.S)
4.379204 GB/Sec (with prefault)
Routine x86-64-movsq (movsq-based memcpy() in arch/x86/lib/memcpy_64.S)
4.264465 GB/Sec (with prefault)
Routine x86-64-movsb (movsb-based memcpy() in arch/x86/lib/memcpy_64.S)
6.554111 GB/Sec (with prefault)Is this skylake? And why are the numbers so low? Even on my laptop (Haswell), I get ~21GB/s (when setting cpufreq to performance).
It's interesting that 'movsb' for you is so much better. It's been promising before, and it *should* be able to do better than manual copying, but it's not been that noticeable on the machines I've tested. But I haven't ued Skylake or Broadwell yet.
cpufreq might be making a difference too. Maybe it's just ramping up the CPU? Or is that really repeatable?
Linus
Re: [PATCH 02/14] perf/bench: Default to all routines in 'perf bench mem'
Quoted 13 lines · Linus Torvalds
Quoted 11 lines · Ingo Molnar
triton:~> perf bench mem all # Running mem/memcpy benchmark... Routine default (Default memcpy() provided by glibc) 4.957170 GB/Sec (with prefault) Routine x86-64-unrolled (unrolled memcpy() in arch/x86/lib/memcpy_64.S) 4.379204 GB/Sec (with prefault) Routine x86-64-movsq (movsq-based memcpy() in arch/x86/lib/memcpy_64.S) 4.264465 GB/Sec (with prefault) Routine x86-64-movsb (movsb-based memcpy() in arch/x86/lib/memcpy_64.S) 6.554111 GB/Sec (with prefault)
Quoted 2 lines
Is this skylake? And why are the numbers so low? Even on my laptop (Haswell), I get ~21GB/s (when setting cpufreq to performance).
No, this was on my desktop, which is a water cooled IvyBridge running at 3.6GHz:
processor : 11 vendor_id : GenuineIntel cpu family : 6 model : 62 model name : Intel(R) Core(TM) i7-4960X CPU @ 3.60GHz stepping : 4 microcode : 0x416 cpu MHz : 1303.031 cache size : 15360 KB
and I didn't really think about the validity of the numbers when I made the changelog, as I rarely benchmark on this box, due to it having various desktop loads running all the time.
AAs you noticed the results are highly variable with default settings:
triton:~/tip> taskset 1 perf stat --null --repeat 10 perf bench mem memcpy -f x86-64-movsb 2>&1 | grep GB
5.580357 GB/sec
5.580357 GB/sec
16.551907 GB/sec
16.551907 GB/sec
15.258789 GB/sec
16.837284 GB/sec
16.837284 GB/sec
16.837284 GB/sec
16.551907 GB/sec
16.837284 GB/secThey get more reliable with '-l 10000' (10,000 loops instead of the default 1):
triton:~/tip> taskset 1 perf stat --null --repeat 10 perf bench mem memcpy -f x86-64-movsb -l 10000 2>&1 | grep GB
15.483591 GB/sec
16.975429 GB/sec
17.088396 GB/sec
20.920407 GB/sec
21.346655 GB/sec
21.322372 GB/sec
21.338306 GB/sec
21.342130 GB/sec
21.339984 GB/sec
21.373145 GB/secthat's purely cached. Also note how after a few seconds it gets faster, due to cpufreq as you suspected.
So once I fix the frequency of all cores to the max, I get much more reliable results:
triton:~/tip> taskset 1 perf stat --null --repeat 10 perf bench mem memcpy -f x86-64-movsb -l 10000 2>&1 | grep -E 'GB|elaps'
21.356879 GB/sec
21.378526 GB/sec
21.351976 GB/sec
21.375203 GB/sec
21.369824 GB/sec
21.353236 GB/sec
21.283708 GB/sec
21.380679 GB/sec
21.347915 GB/sec
21.378572 GB/sec
0.459286278 seconds time elapsed ( +- 0.04% )I'll add a debug check to 'perf bench' to warn about systems that have variable cpufreq running - this is too easy a mistake to make :-/
So with the benchmark stabilized, I get the following results:
triton:~/tip> taskset 1 perf bench mem memcpy -f all -l 10000 # Running 'mem/memcpy' benchmark:
# function 'default' (Default memcpy() provided by glibc) # Copying 1MB bytes ...
18.356783 GB/sec # function 'x86-64-unrolled' (unrolled memcpy() in arch/x86/lib/memcpy_64.S) # Copying 1MB bytes ...
16.294889 GB/sec # function 'x86-64-movsq' (movsq-based memcpy() in arch/x86/lib/memcpy_64.S) # Copying 1MB bytes ...
15.760032 GB/sec # function 'x86-64-movsb' (movsb-based memcpy() in arch/x86/lib/memcpy_64.S) # Copying 1MB bytes ...
21.145818 GB/sec
which matches your observations:
Quoted 7 lines
It's interesting that 'movsb' for you is so much better. It's been promising before, and it *should* be able to do better than manual copying, but it's not been that noticeable on the machines I've tested. But I haven't ued Skylake or Broadwell yet.
cpufreq might be making a difference too. Maybe it's just ramping up the CPU? Or is that really repeatable?
So modulo the cpufreq multiplier it seems repeatable on this IB system - will try it on SkyLake as well.
Before relying on it I also wanted to implement the following 'perf bench' improvements:
- make it more representative of kernel usage by benchmarking a list of characteristic lengths, not just the single stupid 1MB buffer. At smaller buffer sizes I'd expect MOVSB to have even more of a fundamental advantage (due to having all the differentiation in hardware) - but we don't know the latencies of those cases, some of which are in microcode I suspect.
- measure aligned/unaligned buffer address and length effects as well
- measure cache-cold numbers as well. This is pretty hard but not impossible.
With that we could start validating our fundamental memory op routines in user-space.
Thanks,
Ingo
tip-bot for Ingo Molnar
merge bot[tip:perf/core] perf bench: Default to all routines in ' perf bench mem'
In reply to Ingo Molnarperf bench: Default to all routines in 'perf bench mem'
Commit-ID: 276197415685e2a91ce367562800cf0f8fbe482c Gitweb: http://git.kernel.org/tip/276197415685e2a91ce367562800cf0f8fbe482c Author: Ingo Molnar <[email protected]> AuthorDate: Mon, 19 Oct 2015 10:04:18 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Mon, 19 Oct 2015 15:05:34 -0300
perf bench: Default to all routines in 'perf bench mem'
So few people know that the --routine option to 'perf bench memcpy/memset' exists, and would not know that it's capable of testing the kernel's memcpy/memset implementations.
Furthermore, 'perf bench mem all' will not run all routines:
vega:~> perf bench mem all
# Running mem/memcpy benchmark...
Routine default (Default memcpy() provided by glibc) # Copying 1MB Bytes ...
894.454383 MB/Sec
3.844734 GB/Sec (with prefault)
# Running mem/memset benchmark...
Routine default (Default memset() provided by glibc) # Copying 1MB Bytes ...
1.220703 GB/Sec
9.042245 GB/Sec (with prefault)
Because misleadingly the 'all' refers to 'all sub-benchmarks', not 'all sub-benchmarks and routines'.
Fix all this by making the memcpy/memset routine to default to 'all', which results in all the benchmarks being run:
triton:~> perf bench mem all # Running mem/memcpy benchmark... Routine default (Default memcpy() provided by glibc) # Copying 1MB Bytes ... 1.448906 GB/Sec 4.957170 GB/Sec (with prefault) Routine x86-64-unrolled (unrolled memcpy() in arch/x86/lib/memcpy_64.S) # Copying 1MB Bytes ... 1.614153 GB/Sec 4.379204 GB/Sec (with prefault) Routine x86-64-movsq (movsq-based memcpy() in arch/x86/lib/memcpy_64.S) # Copying 1MB Bytes ... 1.570036 GB/Sec 4.264465 GB/Sec (with prefault) Routine x86-64-movsb (movsb-based memcpy() in arch/x86/lib/memcpy_64.S) # Copying 1MB Bytes ... 1.788576 GB/Sec 6.554111 GB/Sec (with prefault) # Running mem/memset benchmark... Routine default (Default memset() provided by glibc) # Copying 1MB Bytes ... 2.082223 GB/Sec 9.126752 GB/Sec (with prefault) Routine x86-64-unrolled (unrolled memset() in arch/x86/lib/memset_64.S) # Copying 1MB Bytes ... 5.710892 GB/Sec 8.346688 GB/Sec (with prefault) Routine x86-64-stosq (movsq-based memset() in arch/x86/lib/memset_64.S) # Copying 1MB Bytes ... 9.765625 GB/Sec 12.520032 GB/Sec (with prefault) Routine x86-64-stosb (movsb-based memset() in arch/x86/lib/memset_64.S) # Copying 1MB Bytes ... 9.668936 GB/Sec 12.682630 GB/Sec (with prefault)
--- tools/perf/bench/mem-memcpy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/perf/bench/mem-memcpy.c +2 -2
@@ -24,7 +24,7 @@#define K 1024static const char *length_str ="1MB" ; -static const char *routine ="default" ; +static const char *routine ="all" ;static int iterations =1 ;static bool use_cycle;static int cycle_fd;
@@ -35,7 +35,7 @@ static const struct option options[] = {OPT_STRING ('l' ,"length" , &length_str,"1MB" ,"Specify length of memory to copy. " "Available units: B, KB, MB, GB and TB (upper and lower)" ), -OPT_STRING ('r' ,"routine" , &routine,"default" , +OPT_STRING ('r' ,"routine" , &routine,"all" ,"Specify routine to copy, \"all\" runs all available routines" ),OPT_INTEGER ('i' ,"iterations" , &iterations, "repeat memcpy() invocation this number of times"),
PATCH 3/14 perf/bench: Eliminate unused argument from bench_mem_common()
In reply to Ingo Molnar--- tools/perf/bench/mem-memcpy.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-)
tools/perf/bench/mem-memcpy.c +4 -7
@@ -211,9 +211,7 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l } } -static int bench_mem_common (int argc,const char **argv, -const char *prefix__maybe_unused , -struct bench_mem_info *info) +static int bench_mem_common (int argc,const char **argv,struct bench_mem_info *info) {int i;size_t len;
@@ -326,8 +324,7 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t len, bool preturn (double )(((double )len * iterations) /timeval2double (&tv_diff)); } -int bench_mem_memcpy (int argc,const char **argv, -const char *prefix__maybe_unused ) +int bench_mem_memcpy (int argc,const char **argv,const char *prefix__maybe_unused ) {struct bench_mem_info info = { .routines = memcpy_routines,
@@ -336,7 +333,7 @@ int bench_mem_memcpy(int argc, const char **argv, .usage = bench_mem_memcpy_usage, }; -return bench_mem_common (argc, argv, prefix, &info); +return bench_mem_common (argc, argv, &info); }static void memset_alloc_mem (void **dst,size_t length)
@@ -419,5 +416,5 @@ int bench_mem_memset(int argc, const char **argv, const char *prefix __maybe_unu .usage = bench_mem_memset_usage, }; -return bench_mem_common (argc, argv, prefix, &info); +return bench_mem_common (argc, argv, &info); }
Signature · 1 line
2.1.4
tip-bot for Ingo Molnar
merge bot[tip:perf/core] perf bench: Eliminate unused argument from bench_mem_common()
perf bench: Eliminate unused argument from bench_mem_common()
Commit-ID: 2946f59ac31d703738c00c684613d289e8d001ea Gitweb: http://git.kernel.org/tip/2946f59ac31d703738c00c684613d289e8d001ea Author: Ingo Molnar <[email protected]> AuthorDate: Mon, 19 Oct 2015 10:04:19 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Mon, 19 Oct 2015 15:29:08 -0300
perf bench: Eliminate unused argument from bench_mem_common()
--- tools/perf/bench/mem-memcpy.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-)
tools/perf/bench/mem-memcpy.c +4 -7
@@ -211,9 +211,7 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l } } -static int bench_mem_common (int argc,const char **argv, -const char *prefix__maybe_unused , -struct bench_mem_info *info) +static int bench_mem_common (int argc,const char **argv,struct bench_mem_info *info) {int i;size_t len;
@@ -326,8 +324,7 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t len, bool preturn (double )(((double )len * iterations) /timeval2double (&tv_diff)); } -int bench_mem_memcpy (int argc,const char **argv, -const char *prefix__maybe_unused ) +int bench_mem_memcpy (int argc,const char **argv,const char *prefix__maybe_unused ) {struct bench_mem_info info = { .routines = memcpy_routines,
@@ -336,7 +333,7 @@ int bench_mem_memcpy(int argc, const char **argv, .usage = bench_mem_memcpy_usage, }; -return bench_mem_common (argc, argv, prefix, &info); +return bench_mem_common (argc, argv, &info); }static void memset_alloc_mem (void **dst,size_t length)
@@ -419,5 +416,5 @@ int bench_mem_memset(int argc, const char **argv, const char *prefix __maybe_unu .usage = bench_mem_memset_usage, }; -return bench_mem_common (argc, argv, prefix, &info); +return bench_mem_common (argc, argv, &info); }
PATCH 4/14 perf/bench: Rename 'mem-memcpy.c' => 'mem-functions.c'
In reply to Ingo MolnarSo mem-memcpy.c started out as a simple memcpy() benchmark, then it grew memset() functionality and now I plan to add string copy benchmarks as well.
This makes the file name a misnomer: rename it to the more generic mem-functions.c name.
--- tools/perf/bench/Build | 2 +- tools/perf/bench/mem-functions.c | 420 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 421 insertions(+), 1 deletion(-)
tools/perf/bench/Build +1 -1
@@ -1,6 +1,6 @@ perf-y += sched-messaging.o perf-y += sched-pipe.o -perf-y += mem-memcpy.o +perf-y += mem-functions.o perf-y += futex-hash.o perf-y += futex-wake.o perf-y += futex-wake-parallel.o
tools/perf/bench/mem-functions.c new file +420 -0
420 lines not on this page · raw message
Signature · 1 line
2.1.4
Re: [PATCH 04/14] perf/bench: Rename 'mem-memcpy.c' => 'mem-functions.c'
Em Mon, Oct 19, 2015 at 10:04:20AM +0200, Ingo Molnar escreveu:
Quoted 17 lines
So
mem-memcpy.cstarted out as a simplememcpy()benchmark, then it grewmemset()functionality and now I plan to add string copy benchmarks as well.This makes the file name a misnomer: rename it to the more generic
mem-functions.cname.Cc Arnaldo Carvalho de Melo <[email protected]>Cc David Ahern <[email protected]>Cc Hitoshi Mitake <[email protected]>Cc Jiri Olsa <[email protected]>Cc Linus Torvalds <[email protected]>Cc Namhyung Kim <[email protected]>Cc Peter Zijlstra <[email protected]>Cc Thomas Gleixner <[email protected]>Signed-off-by Ingo Molnar <[email protected]>
Quoted 3 lines
--- tools/perf/bench/Build | 2 +- tools/perf/bench/mem-functions.c | 420 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Oops, this is not renaming anything, right? And it also introducs __unused usage, which breaks the build.
Lemme try to do it...
- Arnaldo
Quoted 442 lines
2 files changed, 421 insertions(+), 1 deletion(-)tools/perf/bench/Build +1
-1@@ -1,6 +1,6 @@ perf-y += sched-messaging.o perf-y += sched-pipe.o -perf-y += mem-memcpy.o +perf-y += mem-functions.o perf-y += futex-hash.o perf-y += futex-wake.o perf-y += futex-wake-parallel.otools/perf/bench/mem-functions.c new file +420
-0@@ -0,0 +1,420 @@ +/* +* mem-functions.c +* +* Simple memcpy() and memset() benchmarks. +* +* Written by Hitoshi Mitake <[email protected]> +*/ + +#include "../perf.h" +#include "../util/util.h" +#include "../util/parse-options.h" +#include "../util/header.h" +#include "../util/cloexec.h" +#include "bench.h" +#include "mem-memcpy-arch.h" +#include "mem-memset-arch.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/time.h> +#include <errno.h> + +#define K 1024 + +static const char *length_str ="1MB" ; +static const char *routine ="all" ; +static int iterations =1 ; +static bool use_cycle; +static int cycle_fd; +static bool only_prefault; +static bool no_prefault; + +static const struct option options[] = { +OPT_STRING ('l' ,"length" , &length_str,"1MB" , +"Specify length of memory to copy. " +"Available units: B, KB, MB, GB and TB (upper and lower)" ), +OPT_STRING ('r' ,"routine" , &routine,"all" , +"Specify routine to copy, \"all\" runs all available routines" ), +OPT_INTEGER ('i' ,"iterations" , &iterations, +"repeat memcpy() invocation this number of times" ), +OPT_BOOLEAN ('c' ,"cycle" , &use_cycle, +"Use cycles event instead of gettimeofday() for measuring" ), +OPT_BOOLEAN ('o' ,"only-prefault" , &only_prefault, +"Show only the result with page faults before memcpy()" ), +OPT_BOOLEAN ('n' ,"no-prefault" , &no_prefault, +"Show only the result without page faults before memcpy()" ), +OPT_END () +}; + +typedef void *(*memcpy_t )(void *,const void *,size_t ); +typedef void *(*memset_t )(void *,int ,size_t ); + +struct routine { +const char *name; +const char *desc; +union { +memcpy_t memcpy; +memset_t memset; + } fn; +}; + +struct routine memcpy_routines[] = { + { .name ="default" , + .desc ="Default memcpy() provided by glibc" , + .fn.memcpy = memcpy }, + +#ifdef HAVE_ARCH_X86_64_SUPPORT +# define MEMCPY_FN(_fn, _name, _desc) {.name = _name, .desc = _desc, .fn.memcpy = _fn}, +# include "mem-memcpy-x86-64-asm-def.h" +# undef MEMCPY_FN +#endif + + {NULL , } +}; + +static const char *const bench_mem_memcpy_usage[] = { +"perf bench mem memcpy <options>" , +NULL +}; + +static struct perf_event_attr cycle_attr = { + .type =PERF_TYPE_HARDWARE , + .config =PERF_COUNT_HW_CPU_CYCLES +}; + +static void init_cycle (void ) +{ + cycle_fd =sys_perf_event_open (&cycle_attr,getpid (),-1 ,-1 ,perf_event_open_cloexec_flag ()); + +if (cycle_fd <0 && errno ==ENOSYS ) +die ("No CONFIG_PERF_EVENTS=y kernel support configured?\n" ); +else +BUG_ON (cycle_fd <0 ); +} + +static u64 get_cycle (void ) +{ +int ret; +u64 clk; + + ret =read (cycle_fd, &clk,sizeof (u64)); +BUG_ON (ret !=sizeof (u64)); + +return clk; +} + +static double timeval2double (struct timeval *ts) +{ +return (double )ts->tv_sec + (double )ts->tv_usec / (double )1000000 ; +} + +#define print_bps (x) do { \ + if (x < K) \ + printf(" %14lf B/Sec", x); \ + else if (x < K * K) \ + printf(" %14lfd KB/Sec", x / K); \ + else if (x < K * K * K) \ + printf(" %14lf MB/Sec", x / K / K); \ + else \ + printf(" %14lf GB/Sec", x / K / K / K); \ + } while (0) + +struct bench_mem_info { +const struct routine *routines; +u64 (*do_cycle)(const struct routine *r,size_t len,bool prefault); +double (*do_gettimeofday)(const struct routine *r,size_t len,bool prefault); +const char *const *usage; +}; + +static void __bench_mem_routine (struct bench_mem_info *info,int r_idx,size_t len,double totallen) +{ +const struct routine *r = &info->routines[r_idx]; +double result_bps[2 ]; +u64 result_cycle[2 ]; +int prefault = no_prefault ?0 :1 ; + + result_cycle[0 ] = result_cycle[1 ] =0ULL ; + result_bps[0 ] = result_bps[1 ] =0.0 ; + +printf ("Routine %s (%s)\n" , r->name, r->desc); + +if (bench_format ==BENCH_FORMAT_DEFAULT ) +printf ("# Copying %s Bytes ...\n\n" , length_str); + +if (!only_prefault && prefault) { +/* Show both results: */ +if (use_cycle) { + result_cycle[0 ] = info->do_cycle (r, len, false); + result_cycle[1 ] = info->do_cycle (r, len, true); + }else { + result_bps[0 ] = info->do_gettimeofday (r, len, false); + result_bps[1 ] = info->do_gettimeofday (r, len, true); + } + }else { +if (use_cycle) + result_cycle[prefault] = info->do_cycle (r, len, only_prefault); +else + result_bps[prefault] = info->do_gettimeofday (r, len, only_prefault); + } + +switch (bench_format) { +case BENCH_FORMAT_DEFAULT : +if (!only_prefault && prefault) { +if (use_cycle) { +printf (" %14lf Cycle/Byte\n" , + (double )result_cycle[0 ] + / totallen); +printf (" %14lf Cycle/Byte (with prefault)\n" , + (double )result_cycle[1 ] + / totallen); + }else { +print_bps (result_bps[0 ]); +printf ("\n" ); +print_bps (result_bps[1 ]); +printf (" (with prefault)\n" ); + } + }else { +if (use_cycle) { +printf (" %14lf Cycle/Byte" , + (double )result_cycle[prefault] + / totallen); + }else +print_bps (result_bps[prefault]); + +printf ("%s\n" , only_prefault ?" (with prefault)" :"" ); + } +break ; +case BENCH_FORMAT_SIMPLE : +if (!only_prefault && prefault) { +if (use_cycle) { +printf ("%lf %lf\n" , + (double )result_cycle[0 ] / totallen, + (double )result_cycle[1 ] / totallen); + }else { +printf ("%lf %lf\n" , + result_bps[0 ], result_bps[1 ]); + } + }else { +if (use_cycle) { +printf ("%lf\n" , (double )result_cycle[prefault] + / totallen); + }else +printf ("%lf\n" , result_bps[prefault]); + } +break ; +default : +/* Reaching this means there's some disaster: */ +die ("unknown format: %d\n" , bench_format); +break ; + } +} + +static int bench_mem_common (int argc,const char **argv,struct bench_mem_info *info) +{ +int i; +size_t len; +double totallen; + + argc =parse_options (argc, argv, options, info->usage,0 ); + +if (no_prefault && only_prefault) { +fprintf (stderr,"Invalid options: -o and -n are mutually exclusive\n" ); +return 1 ; + } + +if (use_cycle) +init_cycle (); + + len = (size_t )perf_atoll ((char *)length_str); + totallen = (double )len * iterations; + +if ((s64 )len <=0 ) { +fprintf (stderr,"Invalid length:%s\n" , length_str); +return 1 ; + } + +/* Same as without specifying either of prefault and no-prefault: */ +if (only_prefault && no_prefault) + only_prefault = no_prefault = false; + +if (!strncmp (routine,"all" ,3 )) { +for (i =0 ; info->routines[i].name; i++) +__bench_mem_routine (info, i, len, totallen); +return 0 ; + } + +for (i =0 ; info->routines[i].name; i++) { +if (!strcmp (info->routines[i].name, routine)) +break ; + } +if (!info->routines[i].name) { +printf ("Unknown routine:%s\n" , routine); +printf ("Available routines...\n" ); +for (i =0 ; info->routines[i].name; i++) { +printf ("\t%s ... %s\n" , + info->routines[i].name, info->routines[i].desc); + } +return 1 ; + } + +__bench_mem_routine (info, i, len, totallen); + +return 0 ; +} + +static void memcpy_alloc_mem (void **dst,void **src,size_t length) +{ + *dst =zalloc (length); +if (!*dst) +die ("memory allocation failed - maybe length is too large?\n" ); + + *src =zalloc (length); +if (!*src) +die ("memory allocation failed - maybe length is too large?\n" ); + +/* Make sure to always prefault zero pages even if MMAP_THRESH is crossed: */ +memset (*src,0 , length); +} + +static u64 do_memcpy_cycle (const struct routine *r,size_t len,bool prefault) +{ +u64 cycle_start =0ULL , cycle_end =0ULL ; +void *src =NULL , *dst =NULL ; +memcpy_t fn = r->fn.memcpy; +int i; + +memcpy_alloc_mem (&dst, &src, len); + +if (prefault) +fn (dst, src, len); + + cycle_start =get_cycle (); +for (i =0 ; i < iterations; ++i) +fn (dst, src, len); + cycle_end =get_cycle (); + +free (src); +free (dst); +return cycle_end - cycle_start; +} + +static double do_memcpy_gettimeofday (const struct routine *r,size_t len,bool prefault) +{ +struct timeval tv_start, tv_end, tv_diff; +memcpy_t fn = r->fn.memcpy; +void *src =NULL , *dst =NULL ; +int i; + +memcpy_alloc_mem (&dst, &src, len); + +if (prefault) +fn (dst, src, len); + +BUG_ON (gettimeofday (&tv_start,NULL )); +for (i =0 ; i < iterations; ++i) +fn (dst, src, len); +BUG_ON (gettimeofday (&tv_end,NULL )); + +timersub (&tv_end, &tv_start, &tv_diff); + +free (src); +free (dst); +return (double )(((double )len * iterations) /timeval2double (&tv_diff)); +} + +int bench_mem_memcpy(int argc, const char **argv, const char *prefix __unused) +{ +struct bench_mem_info info = { + .routines = memcpy_routines, + .do_cycle = do_memcpy_cycle, + .do_gettimeofday = do_memcpy_gettimeofday, + .usage = bench_mem_memcpy_usage, + }; + +return bench_mem_common (argc, argv, &info); +} + +static void memset_alloc_mem (void **dst,size_t length) +{ + *dst =zalloc (length); +if (!*dst) +die ("memory allocation failed - maybe length is too large?\n" ); +} + +static u64 do_memset_cycle (const struct routine *r,size_t len,bool prefault) +{ +u64 cycle_start =0ULL , cycle_end =0ULL ; +memset_t fn = r->fn.memset; +void *dst =NULL ; +int i; + +memset_alloc_mem (&dst, len); + +if (prefault) +fn (dst,-1 , len); + + cycle_start =get_cycle (); +for (i =0 ; i < iterations; ++i) +fn (dst, i, len); + cycle_end =get_cycle (); + +free (dst); +return cycle_end - cycle_start; +} + +static double do_memset_gettimeofday (const struct routine *r,size_t len, +bool prefault) +{ +struct timeval tv_start, tv_end, tv_diff; +memset_t fn = r->fn.memset; +void *dst =NULL ; +int i; + +memset_alloc_mem (&dst, len); + +if (prefault) +fn (dst,-1 , len); + +BUG_ON (gettimeofday (&tv_start,NULL )); +for (i =0 ; i < iterations; ++i) +fn (dst, i, len); +BUG_ON (gettimeofday (&tv_end,NULL )); + +timersub (&tv_end, &tv_start, &tv_diff); + +free (dst); +return (double )(((double )len * iterations) /timeval2double (&tv_diff)); +} + +static const char *const bench_mem_memset_usage[] = { +"perf bench mem memset <options>" , +NULL +}; + +static const struct routine memset_routines[] = { + { .name ="default" , + .desc ="Default memset() provided by glibc" , + .fn.memset = memset }, + +#ifdef HAVE_ARCH_X86_64_SUPPORT +# define MEMSET_FN(_fn, _name, _desc) { .name = _name, .desc = _desc, .fn.memset = _fn }, +# include "mem-memset-x86-64-asm-def.h" +# undef MEMSET_FN +#endif + + {NULL , } +}; + +int bench_mem_memset(int argc, const char **argv, const char *prefix __unused) +{ +struct bench_mem_info info = { + .routines = memset_routines, + .do_cycle = do_memset_cycle, + .do_gettimeofday = do_memset_gettimeofday, + .usage = bench_mem_memset_usage, + }; + +return bench_mem_common (argc, argv, &info); +}Signature · 1 line
2.1.4
Re: [PATCH 04/14] perf/bench: Rename 'mem-memcpy.c' => 'mem-functions.c'
Em Mon, Oct 19, 2015 at 04:35:20PM -0200, Arnaldo Carvalho de Melo escreveu:
Quoted 22 lines
Em Mon, Oct 19, 2015 at 10:04:20AM +0200, Ingo Molnar escreveu:
Quoted 17 lines
So
mem-memcpy.cstarted out as a simplememcpy()benchmark, then it grewmemset()functionality and now I plan to add string copy benchmarks as well.This makes the file name a misnomer: rename it to the more generic
mem-functions.cname.Cc Arnaldo Carvalho de Melo <[email protected]>Cc David Ahern <[email protected]>Cc Hitoshi Mitake <[email protected]>Cc Jiri Olsa <[email protected]>Cc Linus Torvalds <[email protected]>Cc Namhyung Kim <[email protected]>Cc Peter Zijlstra <[email protected]>Cc Thomas Gleixner <[email protected]>Signed-off-by Ingo Molnar <[email protected]>Quoted 3 lines
--- tools/perf/bench/Build | 2 +- tools/perf/bench/mem-functions.c | 420 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Quoted 4 lines
Oops, this is not renaming anything, right? And it also introducs
__unusedusage, which breaks the build.Lemme try to do it...
Just after applying this patch, I tried a diff and figure this, fixing it by just renaming it.
$ diff -u tools/perf/bench/mem-memcpy.c tools/perf/bench/mem-functions.c --- tools/perf/bench/mem-memcpy.c 2015-10-19 15:29:08.761643798 -0300 +++ tools/perf/bench/mem-functions.c 2015-10-19 15:35:34.986776289 -0300 @@ -1,7 +1,7 @@ /* - * mem-memcpy.c + * mem-functions.c * - * Simple memcpy() and memset() benchmarks + * Simple memcpy() and memset() benchmarks. * * Written by Hitoshi Mitake <[email protected]> */ @@ -324,7 +324,7 @@ return (double)(((double)len * iterations) / timeval2double(&tv_diff)); }
-int bench_mem_memcpy(int argc, const char **argv, const char *prefix __maybe_unused) +int bench_mem_memcpy(int argc, const char **argv, const char *prefix __unused)
{
struct bench_mem_info info = {
.routines = memcpy_routines,
@@ -407,7 +407,7 @@
{ NULL, }
};
-int bench_mem_memset(int argc, const char **argv, const char *prefix __maybe_unused) +int bench_mem_memset(int argc, const char **argv, const char *prefix __unused)
{
struct bench_mem_info info = {
.routines = memset_routines,
tip-bot for Ingo Molnar
merge bot[tip:perf/core] perf bench: Rename 'mem-memcpy.c' => ' mem-functions.c'
In reply to Ingo Molnarperf bench: Rename 'mem-memcpy.c' => 'mem-functions.c'
Commit-ID: 9b2fa7f3e7799a335fd839906ab4d45b7d595dc4 Gitweb: http://git.kernel.org/tip/9b2fa7f3e7799a335fd839906ab4d45b7d595dc4 Author: Ingo Molnar <[email protected]> AuthorDate: Mon, 19 Oct 2015 10:04:20 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Mon, 19 Oct 2015 15:39:39 -0300
perf bench: Rename 'mem-memcpy.c' => 'mem-functions.c'
So mem-memcpy.c started out as a simple memcpy() benchmark, then it grew memset() functionality and now I plan to add string copy benchmarks as well.
This makes the file name a misnomer: rename it to the more generic mem-functions.c name.
[ The "rename" was introducing __unused, wasn't removing the old file,
and didn't update tools/perf/bench/Build, fix it ]
---
tools/perf/bench/Build | 2 +-
tools/perf/bench/{mem-memcpy.c => mem-functions.c} | 0
2 files changed, 1 insertion(+), 1 deletion(-)tools/perf/bench/Build +1 -1
@@ -1,6 +1,6 @@ perf-y += sched-messaging.o perf-y += sched-pipe.o -perf-y += mem-memcpy.o +perf-y += mem-functions.o perf-y += futex-hash.o perf-y += futex-wake.o perf-y += futex-wake-parallel.o
tools/perf/bench/mem-functions.c renamed from tools/perf/bench/mem-memcpy.c +0 -0
PATCH 5/14 perf/bench: Remove the prefaulting complication from 'perf bench mem mem*'
In reply to Ingo MolnarSo 'perf bench mem memcpy/memset' has elaborate code to measure memcpy()/memset() performance both with freshly allocated buffers (which includes initial page fault overhead) and with preallocated buffers.
But the thing is, the resulting bandwidth results are mostly meaningless, because page faults dominate so much of the cost.
It might make sense to measure cache cold vs. cache hot performance, but the code does not do this.
So remove this complication, and always prefault the ranges before using them.
--- tools/perf/bench/mem-functions.c | 146 ++++++++++++++++++++--------------------------------------- 1 file changed, 50 insertions(+), 96 deletions(-)
tools/perf/bench/mem-functions.c +50 -96
@@ -28,8 +28,6 @@ static const char *routine = "all";static int iterations =1 ;static bool use_cycle;static int cycle_fd; -static bool only_prefault; -static bool no_prefault;static const struct option options[] = { OPT_STRING('l', "length", &length_str, "1MB",
@@ -41,10 +39,6 @@ static const struct option options[] = { "repeat memcpy() invocation this number of times"),OPT_BOOLEAN ('c' ,"cycle" , &use_cycle,"Use cycles event instead of gettimeofday() for measuring" ), -OPT_BOOLEAN ('o' ,"only-prefault" , &only_prefault, -"Show only the result with page faults before memcpy()" ), -OPT_BOOLEAN ('n' ,"no-prefault" , &no_prefault, -"Show only the result without page faults before memcpy()" ), OPT_END() };
@@ -110,103 +104,60 @@ static double timeval2double(struct timeval *ts)return (double )ts->tv_sec + (double )ts->tv_usec / (double )1000000 ; } -#define print_bps (x) do { \ - if (x < K) \ - printf(" %14lf B/Sec", x); \ - else if (x < K * K) \ - printf(" %14lfd KB/Sec", x / K); \ - else if (x < K * K * K) \ - printf(" %14lf MB/Sec", x / K / K); \ - else \ - printf(" %14lf GB/Sec", x / K / K / K); \ +#define print_bps (x) do { \ + if (x < K) \ + printf(" %14lf B/Sec\n", x); \ + else if (x < K * K) \ + printf(" %14lfd KB/Sec\n", x / K); \ + else if (x < K * K * K) \ + printf(" %14lf MB/Sec\n", x / K / K); \ + else \ + printf(" %14lf GB/Sec\n", x / K / K / K); \ } while (0)struct bench_mem_info {const struct routine *routines; -u64 (*do_cycle)(const struct routine *r,size_t len,bool prefault); -double (*do_gettimeofday)(const struct routine *r,size_t len,bool prefault); +u64 (*do_cycle)(const struct routine *r,size_t len); +double (*do_gettimeofday)(const struct routine *r,size_t len);const char *const *usage; };static void __bench_mem_routine (struct bench_mem_info *info,int r_idx,size_t len,double totallen) {const struct routine *r = &info->routines[r_idx]; -double result_bps[2 ]; -u64 result_cycle[2 ]; -int prefault = no_prefault ?0 :1 ; - - result_cycle[0 ] = result_cycle[1 ] =0ULL ; - result_bps[0 ] = result_bps[1 ] =0.0 ; +double result_bps =0.0 ; +u64 result_cycle =0 ;printf ("Routine %s (%s)\n" , r->name, r->desc);if (bench_format ==BENCH_FORMAT_DEFAULT )printf ("# Copying %s Bytes ...\n\n" , length_str); -if (!only_prefault && prefault) { -/* Show both results: */ -if (use_cycle) { - result_cycle[0 ] = info->do_cycle (r, len, false); - result_cycle[1 ] = info->do_cycle (r, len, true); - }else { - result_bps[0 ] = info->do_gettimeofday (r, len, false); - result_bps[1 ] = info->do_gettimeofday (r, len, true); - } +if (use_cycle) { + result_cycle = info->do_cycle (r, len); }else { -if (use_cycle) - result_cycle[prefault] = info->do_cycle (r, len, only_prefault); -else - result_bps[prefault] = info->do_gettimeofday (r, len, only_prefault); + result_bps = info->do_gettimeofday (r, len); }switch (bench_format) {case BENCH_FORMAT_DEFAULT : -if (!only_prefault && prefault) { -if (use_cycle) { -printf (" %14lf Cycle/Byte\n" , - (double )result_cycle[0 ] - / totallen); -printf (" %14lf Cycle/Byte (with prefault)\n" , - (double )result_cycle[1 ] - / totallen); - }else { -print_bps (result_bps[0 ]); -printf ("\n" ); -print_bps (result_bps[1 ]); -printf (" (with prefault)\n" ); - } +if (use_cycle) { +printf (" %14lf Cycle/Byte\n" , (double )result_cycle/totallen); }else { -if (use_cycle) { -printf (" %14lf Cycle/Byte" , - (double )result_cycle[prefault] - / totallen); - }else -print_bps (result_bps[prefault]); - -printf ("%s\n" , only_prefault ?" (with prefault)" :"" ); +print_bps (result_bps); }break ; +case BENCH_FORMAT_SIMPLE : -if (!only_prefault && prefault) { -if (use_cycle) { -printf ("%lf %lf\n" , - (double )result_cycle[0 ] / totallen, - (double )result_cycle[1 ] / totallen); - }else { -printf ("%lf %lf\n" , - result_bps[0 ], result_bps[1 ]); - } +if (use_cycle) { +printf ("%lf\n" , (double )result_cycle/totallen); }else { -if (use_cycle) { -printf ("%lf\n" , (double )result_cycle[prefault] - / totallen); - }else -printf ("%lf\n" , result_bps[prefault]); +printf ("%lf\n" , result_bps); }break ; +default : -/* Reaching this means there's some disaster: */ -die ("unknown format: %d\n" , bench_format); +BUG_ON (1 );break ; } }
@@ -219,11 +170,6 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info * argc =parse_options (argc, argv, options, info->usage,0 ); -if (no_prefault && only_prefault) { -fprintf (stderr,"Invalid options: -o and -n are mutually exclusive\n" ); -return 1 ; - } -if (use_cycle)init_cycle ();
@@ -235,10 +181,6 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *return 1 ; } -/* Same as without specifying either of prefault and no-prefault: */ -if (only_prefault && no_prefault) - only_prefault = no_prefault = false; -if (!strncmp (routine,"all" ,3 )) {for (i =0 ; info->routines[i].name; i++)__bench_mem_routine (info, i, len, totallen);
@@ -278,7 +220,7 @@ static void memcpy_alloc_mem(void **dst, void **src, size_t length)memset (*src,0 , length); } -static u64 do_memcpy_cycle (const struct routine *r,size_t len,bool prefault) +static u64 do_memcpy_cycle (const struct routine *r,size_t len) {u64 cycle_start =0ULL , cycle_end =0ULL ;void *src =NULL , *dst =NULL ;
@@ -287,8 +229,11 @@ static u64 do_memcpy_cycle(const struct routine *r, size_t len, bool prefault)memcpy_alloc_mem (&dst, &src, len); -if (prefault) -fn (dst, src, len); +/* +* We prefault the freshly allocated memory range here, +* to not measure page fault overhead: +*/ +fn (dst, src, len); cycle_start =get_cycle ();for (i =0 ; i < iterations; ++i)
@@ -300,7 +245,7 @@ static u64 do_memcpy_cycle(const struct routine *r, size_t len, bool prefault)return cycle_end - cycle_start; } -static double do_memcpy_gettimeofday (const struct routine *r,size_t len,bool prefault) +static double do_memcpy_gettimeofday (const struct routine *r,size_t len) {struct timeval tv_start, tv_end, tv_diff;memcpy_t fn = r->fn.memcpy;
@@ -309,8 +254,11 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t len, bool pmemcpy_alloc_mem (&dst, &src, len); -if (prefault) -fn (dst, src, len); +/* +* We prefault the freshly allocated memory range here, +* to not measure page fault overhead: +*/ +fn (dst, src, len);BUG_ON (gettimeofday (&tv_start,NULL ));for (i =0 ; i < iterations; ++i)
@@ -321,6 +269,7 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t len, bool pfree (src);free (dst); +return (double )(((double )len * iterations) /timeval2double (&tv_diff)); }
@@ -343,7 +292,7 @@ static void memset_alloc_mem(void **dst, size_t length)die ("memory allocation failed - maybe length is too large?\n" ); } -static u64 do_memset_cycle (const struct routine *r,size_t len,bool prefault) +static u64 do_memset_cycle (const struct routine *r,size_t len) {u64 cycle_start =0ULL , cycle_end =0ULL ;memset_t fn = r->fn.memset;
@@ -352,8 +301,11 @@ static u64 do_memset_cycle(const struct routine *r, size_t len, bool prefault)memset_alloc_mem (&dst, len); -if (prefault) -fn (dst,-1 , len); +/* +* We prefault the freshly allocated memory range here, +* to not measure page fault overhead: +*/ +fn (dst,-1 , len); cycle_start =get_cycle ();for (i =0 ; i < iterations; ++i)
@@ -364,8 +316,7 @@ static u64 do_memset_cycle(const struct routine *r, size_t len, bool prefault)return cycle_end - cycle_start; } -static double do_memset_gettimeofday (const struct routine *r,size_t len, -bool prefault) +static double do_memset_gettimeofday (const struct routine *r,size_t len) {struct timeval tv_start, tv_end, tv_diff;memset_t fn = r->fn.memset;
@@ -374,8 +325,11 @@ static double do_memset_gettimeofday(const struct routine *r, size_t len,memset_alloc_mem (&dst, len); -if (prefault) -fn (dst,-1 , len); +/* +* We prefault the freshly allocated memory range here, +* to not measure page fault overhead: +*/ +fn (dst,-1 , len);BUG_ON (gettimeofday (&tv_start,NULL ));for (i =0 ; i < iterations; ++i)
Signature · 1 line
2.1.4
tip-bot for Ingo Molnar
merge bot[tip:perf/core] perf bench: Remove the prefaulting complication from 'perf bench mem mem*'
perf bench: Remove the prefaulting complication from 'perf bench mem mem*'
Commit-ID: 6db175c7333e22ee818373cbea067e3eaa0236f7 Gitweb: http://git.kernel.org/tip/6db175c7333e22ee818373cbea067e3eaa0236f7 Author: Ingo Molnar <[email protected]> AuthorDate: Mon, 19 Oct 2015 10:04:21 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Mon, 19 Oct 2015 16:03:31 -0300
perf bench: Remove the prefaulting complication from 'perf bench mem mem*'
So 'perf bench mem memcpy/memset' has elaborate code to measure memcpy()/memset() performance both with freshly allocated buffers (which includes initial page fault overhead) and with preallocated buffers.
But the thing is, the resulting bandwidth results are mostly meaningless, because page faults dominate so much of the cost.
It might make sense to measure cache cold vs. cache hot performance, but the code does not do this.
So remove this complication, and always prefault the ranges before using them.
--- tools/perf/Documentation/perf-bench.txt | 16 ---- tools/perf/bench/mem-functions.c | 146 +++++++++++--------------------- 2 files changed, 50 insertions(+), 112 deletions(-)
tools/perf/Documentation/perf-bench.txt +0 -16
@@ -157,14 +157,6 @@ Repeat memcpy invocation this number of times. --cycle:: Use perf's cpu-cycles event instead of gettimeofday syscall. --o:: ---only-prefault:: -Show only the result with page faults before memcpy. - --n:: ---no-prefault:: -Show only the result without page faults before memcpy. - *memset*:: Suite for evaluating performance of simple memory set in various ways.
@@ -189,14 +181,6 @@ Repeat memset invocation this number of times. --cycle:: Use perf's cpu-cycles event instead of gettimeofday syscall. --o:: ---only-prefault:: -Show only the result with page faults before memset. - --n:: ---no-prefault:: -Show only the result without page faults before memset. - SUITES FOR 'numa' ~~~~~~~~~~~~~~~~~ *mem*::
tools/perf/bench/mem-functions.c +50 -96
259 lines not on this page · raw message
PATCH 6/14 perf/bench: List output formatting options on 'perf bench -h'
In reply to Ingo MolnarSo 'perf bench -h' is not very helpful when printing the help line about the output formatting options:
-f, --format <default>
Specify format style
There are two output format styles, 'default' and 'simple', so improve the help text to:
-f, --format <default|simple>
Specify the output formatting style
--- tools/perf/bench/mem-functions.c | 4 +- tools/perf/bench/mem-memcpy.c | 420 ----------------------------------------------------------- tools/perf/builtin-bench.c | 2 +- 3 files changed, 3 insertions(+), 423 deletions(-)
tools/perf/bench/mem-functions.c +2 -2
@@ -273,7 +273,7 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t len)return (double )(((double )len * iterations) /timeval2double (&tv_diff)); } -int bench_mem_memcpy(int argc, const char **argv, const char *prefix __unused) +int bench_mem_memcpy (int argc,const char **argv,const char *prefix__maybe_unused ) {struct bench_mem_info info = { .routines = memcpy_routines,
@@ -361,7 +361,7 @@ static const struct routine memset_routines[] = { { NULL, } }; -int bench_mem_memset(int argc, const char **argv, const char *prefix __unused) +int bench_mem_memset (int argc,const char **argv,const char *prefix__maybe_unused ) {struct bench_mem_info info = { .routines = memset_routines,
tools/perf/bench/mem-memcpy.c deleted +0 -420
420 lines not on this page · raw message
tools/perf/builtin-bench.c +1 -1
@@ -110,7 +110,7 @@ int bench_format = BENCH_FORMAT_DEFAULT;unsigned int bench_repeat =10 ;/* default number of times to repeat the run */ static const struct option bench_options[] = { -OPT_STRING ('f' ,"format" , &bench_format_str,"default" ,"Specify format style" ), +OPT_STRING ('f' ,"format" , &bench_format_str,"default|simple" ,"Specify the output formatting style" ),OPT_UINTEGER ('r' ,"repeat" , &bench_repeat,"Specify amount of times to repeat the run" ),OPT_END () };
Signature · 1 line
2.1.4
Re: [PATCH 06/14] perf/bench: List output formatting options on 'perf bench -h'
tools/perf/bench/mem-memcpy.c
Quoted 27 lines · Ingo Molnar
tools/perf/bench/mem-functions.c +2
-2@@ -273,7 +273,7 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t len)return (double )(((double )len * iterations) /timeval2double (&tv_diff)); } -int bench_mem_memcpy(int argc, const char **argv, const char *prefix __unused) +int bench_mem_memcpy (int argc,const char **argv,const char *prefix__maybe_unused ) {struct bench_mem_info info = { .routines = memcpy_routines,@@ -361,7 +361,7 @@ static const struct routine memset_routines[] = { { NULL, } }; -int bench_mem_memset(int argc, const char **argv, const char *prefix __unused) +int bench_mem_memset (int argc,const char **argv,const char *prefix__maybe_unused ) {struct bench_mem_info info = { .routines = memset_routines,tools/perf/bench/mem-memcpy.c deleted +0
-0
All of this seems like leftovers from previous patches.
Re: [PATCH 06/14] perf/bench: List output formatting options on 'perf bench -h'
Em Mon, Oct 19, 2015 at 07:28:56AM -0600, David Ahern escreveu:
Quoted 18 lines · Ingo Molnar
Quoted 17 lines
tools/perf/bench/mem-functions.c +1
-1@@ -273,7 +273,7 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t len)return (double )(((double )len * iterations) /timeval2double (&tv_diff)); } -int bench_mem_memcpy(int argc, const char **argv, const char *prefix __unused) +int bench_mem_memcpy (int argc,const char **argv,const char *prefix__maybe_unused ) {struct bench_mem_info info = { .routines = memcpy_routines,@@ -361,7 +361,7 @@ static const struct routine memset_routines[] = { { NULL, } };
Quoted 12 lines
tools/perf/bench/mem-memcpy.c
Quoted 10 lines
tools/perf/bench/mem-functions.c +1
-1-int bench_mem_memset(int argc, const char **argv, const char *prefix __unused) +int bench_mem_memset (int argc,const char **argv,const char *prefix__maybe_unused ) {struct bench_mem_info info = { .routines = memset_routines,tools/perf/bench/mem-memcpy.c deleted +0
-0All of this seems like leftovers from previous patches.
Right, I fixed this one at the rename point, 4/5 IIRc
tip-bot for Ingo Molnar
merge bot[tip:perf/core] perf bench: List output formatting options on ' perf bench -h'
In reply to Ingo Molnarperf bench: List output formatting options on 'perf bench -h'
Commit-ID: 7a46a8fd13bd60584687f417cd35935965f29ae2 Gitweb: http://git.kernel.org/tip/7a46a8fd13bd60584687f417cd35935965f29ae2 Author: Ingo Molnar <[email protected]> AuthorDate: Mon, 19 Oct 2015 10:04:22 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Mon, 19 Oct 2015 16:03:53 -0300
perf bench: List output formatting options on 'perf bench -h'
So 'perf bench -h' is not very helpful when printing the help line about the output formatting options:
-f, --format <default>
Specify format style
There are two output format styles, 'default' and 'simple', so improve the help text to:
-f, --format <default|simple>
Specify the output formatting style
--- tools/perf/builtin-bench.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/builtin-bench.c +1 -1
@@ -110,7 +110,7 @@ int bench_format = BENCH_FORMAT_DEFAULT;unsigned int bench_repeat =10 ;/* default number of times to repeat the run */ static const struct option bench_options[] = { -OPT_STRING ('f' ,"format" , &bench_format_str,"default" ,"Specify format style" ), +OPT_STRING ('f' ,"format" , &bench_format_str,"default|simple" ,"Specify the output formatting style" ),OPT_UINTEGER ('r' ,"repeat" , &bench_repeat,"Specify amount of times to repeat the run" ),OPT_END () };
PATCH 7/14 perf/bench/mem: Change 'cycle' to 'cycles'
In reply to Ingo MolnarSo 'perf bench mem memset/memcpy' has a CPU cycles measurement method, but calls it 'cycle' (singular) throughout the code, which makes it harder to read.
Rename all related functions, variables and options to a plural 'cycles' nomenclature.
--- tools/perf/bench/mem-functions.c | 56 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 28 deletions(-)
tools/perf/bench/mem-functions.c +28 -28
@@ -26,8 +26,8 @@static const char *length_str ="1MB" ;static const char *routine ="all" ;static int iterations =1 ; -static bool use_cycle; -static int cycle_fd; +static bool use_cycles; +static int cycles_fd;static const struct option options[] = { OPT_STRING('l', "length", &length_str, "1MB",
@@ -37,8 +37,8 @@ static const struct option options[] = { "Specify routine to copy, \"all\" runs all available routines"),OPT_INTEGER ('i' ,"iterations" , &iterations,"repeat memcpy() invocation this number of times" ), -OPT_BOOLEAN ('c' ,"cycle" , &use_cycle, -"Use cycles event instead of gettimeofday() for measuring" ), +OPT_BOOLEAN ('c' ,"cycles" , &use_cycles, +"Use a cycles event instead of gettimeofday() to measure performance" ), OPT_END() };
@@ -78,22 +78,22 @@ static struct perf_event_attr cycle_attr = { .config = PERF_COUNT_HW_CPU_CYCLES }; -static void init_cycle (void ) +static void init_cycles (void ) { - cycle_fd =sys_perf_event_open (&cycle_attr,getpid (),-1 ,-1 ,perf_event_open_cloexec_flag ()); + cycles_fd =sys_perf_event_open (&cycle_attr,getpid (),-1 ,-1 ,perf_event_open_cloexec_flag ()); -if (cycle_fd <0 && errno ==ENOSYS ) +if (cycles_fd <0 && errno ==ENOSYS )die ("No CONFIG_PERF_EVENTS=y kernel support configured?\n" );else -BUG_ON (cycle_fd <0 ); +BUG_ON (cycles_fd <0 ); } -static u64 get_cycle (void ) +static u64 get_cycles (void ) {int ret;u64 clk; - ret =read (cycle_fd, &clk,sizeof (u64)); + ret =read (cycles_fd, &clk,sizeof (u64));BUG_ON (ret !=sizeof (u64));return clk;
@@ -117,7 +117,7 @@ static double timeval2double(struct timeval *ts)struct bench_mem_info {const struct routine *routines; -u64 (*do_cycle)(const struct routine *r,size_t len); +u64 (*do_cycles)(const struct routine *r,size_t len);double (*do_gettimeofday)(const struct routine *r,size_t len);const char *const *usage; };
@@ -126,31 +126,31 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l {const struct routine *r = &info->routines[r_idx];double result_bps =0.0 ; -u64 result_cycle =0 ; +u64 result_cycles =0 ;printf ("Routine %s (%s)\n" , r->name, r->desc);if (bench_format ==BENCH_FORMAT_DEFAULT )printf ("# Copying %s Bytes ...\n\n" , length_str); -if (use_cycle) { - result_cycle = info->do_cycle (r, len); +if (use_cycles) { + result_cycles = info->do_cycles (r, len); }else { result_bps = info->do_gettimeofday (r, len); }switch (bench_format) {case BENCH_FORMAT_DEFAULT : -if (use_cycle) { -printf (" %14lf Cycle/Byte\n" , (double )result_cycle/totallen); +if (use_cycles) { +printf (" %14lf cycles/Byte\n" , (double )result_cycles/totallen); }else {print_bps (result_bps); }break ;case BENCH_FORMAT_SIMPLE : -if (use_cycle) { -printf ("%lf\n" , (double )result_cycle/totallen); +if (use_cycles) { +printf ("%lf\n" , (double )result_cycles/totallen); }else {printf ("%lf\n" , result_bps); }
@@ -170,8 +170,8 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info * argc =parse_options (argc, argv, options, info->usage,0 ); -if (use_cycle) -init_cycle (); +if (use_cycles) +init_cycles (); len = (size_t )perf_atoll ((char *)length_str); totallen = (double )len * iterations;
@@ -220,7 +220,7 @@ static void memcpy_alloc_mem(void **dst, void **src, size_t length)memset (*src,0 , length); } -static u64 do_memcpy_cycle (const struct routine *r,size_t len) +static u64 do_memcpy_cycles (const struct routine *r,size_t len) {u64 cycle_start =0ULL , cycle_end =0ULL ;void *src =NULL , *dst =NULL ;
@@ -235,10 +235,10 @@ static u64 do_memcpy_cycle(const struct routine *r, size_t len)*/ fn (dst, src, len); - cycle_start =get_cycle (); + cycle_start =get_cycles ();for (i =0 ; i < iterations; ++i)fn (dst, src, len); - cycle_end =get_cycle (); + cycle_end =get_cycles ();free (src);free (dst);
@@ -277,7 +277,7 @@ int bench_mem_memcpy(int argc, const char **argv, const char *prefix __maybe_unu {struct bench_mem_info info = { .routines = memcpy_routines, - .do_cycle = do_memcpy_cycle, + .do_cycles = do_memcpy_cycles, .do_gettimeofday = do_memcpy_gettimeofday, .usage = bench_mem_memcpy_usage, };
@@ -292,7 +292,7 @@ static void memset_alloc_mem(void **dst, size_t length)die ("memory allocation failed - maybe length is too large?\n" ); } -static u64 do_memset_cycle (const struct routine *r,size_t len) +static u64 do_memset_cycles (const struct routine *r,size_t len) {u64 cycle_start =0ULL , cycle_end =0ULL ;memset_t fn = r->fn.memset;
@@ -307,10 +307,10 @@ static u64 do_memset_cycle(const struct routine *r, size_t len)*/ fn (dst,-1 , len); - cycle_start =get_cycle (); + cycle_start =get_cycles ();for (i =0 ; i < iterations; ++i)fn (dst, i, len); - cycle_end =get_cycle (); + cycle_end =get_cycles ();free (dst);return cycle_end - cycle_start;
@@ -365,7 +365,7 @@ int bench_mem_memset(int argc, const char **argv, const char *prefix __maybe_unu {struct bench_mem_info info = { .routines = memset_routines, - .do_cycle = do_memset_cycle, + .do_cycles = do_memset_cycles, .do_gettimeofday = do_memset_gettimeofday, .usage = bench_mem_memset_usage, };
Signature · 1 line
2.1.4
tip-bot for Ingo Molnar
merge bot[tip:perf/core] perf bench mem: Change 'cycle' to 'cycles'
perf bench mem: Change 'cycle' to 'cycles'
Commit-ID: b14f2d357675bd7fb4e5a705ac7320a9638ecab5 Gitweb: http://git.kernel.org/tip/b14f2d357675bd7fb4e5a705ac7320a9638ecab5 Author: Ingo Molnar <[email protected]> AuthorDate: Mon, 19 Oct 2015 10:04:23 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Mon, 19 Oct 2015 16:05:01 -0300
perf bench mem: Change 'cycle' to 'cycles'
So 'perf bench mem memset/memcpy' has a CPU cycles measurement method, but calls it 'cycle' (singular) throughout the code, which makes it harder to read.
Rename all related functions, variables and options to a plural 'cycles' nomenclature.
--- tools/perf/Documentation/perf-bench.txt | 4 +-- tools/perf/bench/mem-functions.c | 56 ++++++++++++++++----------------- 2 files changed, 30 insertions(+), 30 deletions(-)
tools/perf/Documentation/perf-bench.txt +2 -2
@@ -154,7 +154,7 @@ On x86-64, x86-64-unrolled, x86-64-movsq and x86-64-movsb are supported. Repeat memcpy invocation this number of times. -c:: ---cycle:: +--cycles:: Use perf's cpu-cycles event instead of gettimeofday syscall. *memset*::
@@ -178,7 +178,7 @@ On x86-64, x86-64-unrolled, x86-64-stosq and x86-64-stosb are supported. Repeat memset invocation this number of times. -c:: ---cycle:: +--cycles:: Use perf's cpu-cycles event instead of gettimeofday syscall. SUITES FOR 'numa'
tools/perf/bench/mem-functions.c +28 -28
160 lines not on this page · raw message
PATCH 8/14 perf/bench/mem: Rename 'routine' to 'routine_str'
In reply to Ingo MolnarSo bench/mem-functions.c has a 'routine' name for the routines parameter string, but a 'length_str' name for the length parameter string.
We also have another entity named 'routine': 'struct routine'.
This is inconsistent and confusing: rename 'routine' to 'routine_str'.
Also fix typos in the --routine help text.
--- tools/perf/bench/mem-functions.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
tools/perf/bench/mem-functions.c +7 -7
@@ -24,7 +24,7 @@#define K 1024static const char *length_str ="1MB" ; -static const char *routine ="all" ; +static const char *routine_str ="all" ;static int iterations =1 ;static bool use_cycles;static int cycles_fd;
@@ -33,8 +33,8 @@ static const struct option options[] = {OPT_STRING ('l' ,"length" , &length_str,"1MB" ,"Specify length of memory to copy. " "Available units: B, KB, MB, GB and TB (upper and lower)" ), -OPT_STRING ('r' ,"routine" , &routine,"all" , -"Specify routine to copy, \"all\" runs all available routines" ), +OPT_STRING ('r' ,"routine" , &routine_str,"all" , +"Specify the routine to run, \"all\" runs all available routines" ),OPT_INTEGER ('i' ,"iterations" , &iterations,"repeat memcpy() invocation this number of times" ), OPT_BOOLEAN('c', "cycles", &use_cycles,
@@ -128,7 +128,7 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t ldouble result_bps =0.0 ;u64 result_cycles =0 ; -printf ("Routine %s (%s)\n" , r->name, r->desc); +printf ("routine %s (%s)\n" , r->name, r->desc);if (bench_format ==BENCH_FORMAT_DEFAULT )printf ("# Copying %s Bytes ...\n\n" , length_str);
@@ -181,18 +181,18 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *return 1 ; } -if (!strncmp (routine,"all" ,3 )) { +if (!strncmp (routine_str,"all" ,3 )) {for (i =0 ; info->routines[i].name; i++)__bench_mem_routine (info, i, len, totallen);return 0 ; }for (i =0 ; info->routines[i].name; i++) { -if (!strcmp (info->routines[i].name, routine)) +if (!strcmp (info->routines[i].name, routine_str))break ; }if (!info->routines[i].name) { -printf ("Unknown routine:%s\n" , routine); +printf ("Unknown routine: %s\n" , routine_str);printf ("Available routines...\n" );for (i =0 ; info->routines[i].name; i++) { printf("\t%s ... %s\n",
Signature · 1 line
2.1.4
Re: [PATCH 08/14] perf/bench/mem: Rename 'routine' to 'routine_str'
tools/perf/bench/mem-functions.c static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l · line 134
Quoted 9 lines · Ingo Molnar
tools/perf/bench/mem-functions.c +1
-1@@ -128,7 +128,7 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t ldouble result_bps =0.0 ;u64 result_cycles =0 ; -printf ("Routine %s (%s)\n" , r->name, r->desc); +printf ("routine %s (%s)\n" , r->name, r->desc);if (bench_format ==BENCH_FORMAT_DEFAULT )printf ("# Copying %s Bytes ...\n\n" , length_str);
Seems like 'R' is more appropriate here.
Re: [PATCH 08/14] perf/bench/mem: Rename 'routine' to 'routine_str'
Em Mon, Oct 19, 2015 at 07:34:46AM -0600, David Ahern escreveu:
Quoted 5 lines · Ingo Molnar
Quoted 4 lines
tools/perf/bench/mem-functions.c +0
-0@@ -128,7 +128,7 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t ldouble result_bps =0.0 ;u64 result_cycles =0 ;
Quoted 7 lines
tools/perf/bench/mem-functions.c static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l · line 134
Quoted 5 lines
tools/perf/bench/mem-functions.c +1
-1-printf ("Routine %s (%s)\n" , r->name, r->desc); +printf ("routine %s (%s)\n" , r->name, r->desc);if (bench_format ==BENCH_FORMAT_DEFAULT )printf ("# Copying %s Bytes ...\n\n" , length_str);Seems like 'R' is more appropriate here.
Right, changed it.
- Arnaldo
Re: [PATCH 08/14] perf/bench/mem: Rename 'routine' to 'routine_str'
Em Mon, Oct 19, 2015 at 04:54:47PM -0200, Arnaldo Carvalho de Melo escreveu:
Quoted 9 lines
Em Mon, Oct 19, 2015 at 07:34:46AM -0600, David Ahern escreveu:
Quoted 8 lines · Ingo Molnar
Quoted 7 lines
tools/perf/bench/mem-functions.c +1
-1@@ -128,7 +128,7 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t ldouble result_bps =0.0 ;u64 result_cycles =0 ; -printf ("Routine %s (%s)\n" , r->name, r->desc); +printf ("routine %s (%s)\n" , r->name, r->desc);
Quoted 6 lines
Quoted 4 lines
tools/perf/bench/mem-functions.c static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l · line 134
Quoted 2 lines
tools/perf/bench/mem-functions.c +0
-0if (bench_format ==BENCH_FORMAT_DEFAULT )printf ("# Copying %s Bytes ...\n\n" , length_str);Seems like 'R' is more appropriate here.
Right, changed it.
And then, he does that on a later patch, duh.
- Arnaldo
Re: [PATCH 08/14] perf/bench/mem: Rename 'routine' to 'routine_str'
Quoted 10 lines · Arnaldo Carvalho de Melo
Em Mon, Oct 19, 2015 at 04:54:47PM -0200, Arnaldo Carvalho de Melo escreveu:
Quoted 9 lines
Em Mon, Oct 19, 2015 at 07:34:46AM -0600, David Ahern escreveu:
Quoted 8 lines · Ingo Molnar
Quoted 7 lines
tools/perf/bench/mem-functions.c +1
-1@@ -128,7 +128,7 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t ldouble result_bps =0.0 ;u64 result_cycles =0 ; -printf ("Routine %s (%s)\n" , r->name, r->desc); +printf ("routine %s (%s)\n" , r->name, r->desc);
Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
tools/perf/bench/mem-functions.c static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l · line 134
Quoted 2 lines
tools/perf/bench/mem-functions.c +0
-0if (bench_format ==BENCH_FORMAT_DEFAULT )printf ("# Copying %s Bytes ...\n\n" , length_str);Seems like 'R' is more appropriate here.
Right, changed it.
And then, he does that on a later patch, duh.
Yeah, indeed - I messed that up: tried to introduce __unused but noticed during development and testing on other distros that '__unused' is way too crowded a namespace (various fields in random headers are named like that), so after a bit of a fight with those headers I changed it back to __maybe_unused ... but the original change slipped into the series.
Do you want me to resend the series to fix this and the other problems David and you noticed?
Thanks,
Ingo
Re: [PATCH 08/14] perf/bench/mem: Rename 'routine' to 'routine_str'
Em Mon, Oct 19, 2015 at 09:09:32PM +0200, Ingo Molnar escreveu:
Quoted 22 lines · Arnaldo Carvalho de Melo
Quoted 11 lines
Em Mon, Oct 19, 2015 at 04:54:47PM -0200, Arnaldo Carvalho de Melo escreveu:
Quoted 9 lines
Em Mon, Oct 19, 2015 at 07:34:46AM -0600, David Ahern escreveu:
Quoted 8 lines · Ingo Molnar
Quoted 7 lines
tools/perf/bench/mem-functions.c +1
-1@@ -128,7 +128,7 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t ldouble result_bps =0.0 ;u64 result_cycles =0 ; -printf ("Routine %s (%s)\n" , r->name, r->desc); +printf ("routine %s (%s)\n" , r->name, r->desc);Quoted 8 lines
Quoted 6 lines
Quoted 4 lines
tools/perf/bench/mem-functions.c static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t l · line 134
Quoted 2 lines
tools/perf/bench/mem-functions.c +0
-0if (bench_format ==BENCH_FORMAT_DEFAULT )printf ("# Copying %s Bytes ...\n\n" , length_str);Seems like 'R' is more appropriate here.
Right, changed it.
And then, he does that on a later patch, duh.
Quoted 8 lines
Yeah, indeed - I messed that up: tried to introduce
__unusedbut noticed during development and testing on other distros that '__unused' is way too crowded a namespace (various fields in random headers are named like that), so after a bit of a fight with those headers I changed it back to__maybe_unused... but the original change slipped into the series.Do you want me to resend the series to fix this and the other problems David and you noticed?
No problem, I fixed it all already :-)
- Arnaldo
Re: [PATCH 08/14] perf/bench/mem: Rename 'routine' to 'routine_str'
Em Mon, Oct 19, 2015 at 05:20:03PM -0200, Arnaldo Carvalho de Melo escreveu:
Quoted 16 lines
Em Mon, Oct 19, 2015 at 09:09:32PM +0200, Ingo Molnar escreveu:
Quoted 15 lines · Arnaldo Carvalho de Melo
Quoted 7 lines
Em Mon, Oct 19, 2015 at 04:54:47PM -0200, Arnaldo Carvalho de Melo escreveu:
Quoted 4 lines
Em Mon, Oct 19, 2015 at 07:34:46AM -0600, David Ahern escreveu:
Quoted 1 line
Seems like 'R' is more appropriate here.
Right, changed it.
And then, he does that on a later patch, duh.
Yeah, indeed - I messed that up: tried to introduce
__unusedbut noticed during development and testing on other distros that '__unused' is way too crowded a namespace (various fields in random headers are named like that), so after a bit of a fight with those headers I changed it back to__maybe_unused... but the original change slipped into the series.
Quoted 4 lines
Quoted 2 lines
Do you want me to resend the series to fix this and the other problems David and you noticed?
No problem, I fixed it all already :-)
Please check my perf/core branch.
- Arnaldo
Re: [PATCH 08/14] perf/bench/mem: Rename 'routine' to 'routine_str'
Quoted 17 lines · Arnaldo Carvalho de Melo
Em Mon, Oct 19, 2015 at 05:20:03PM -0200, Arnaldo Carvalho de Melo escreveu:
Quoted 16 lines
Em Mon, Oct 19, 2015 at 09:09:32PM +0200, Ingo Molnar escreveu:
Quoted 15 lines · Arnaldo Carvalho de Melo
Quoted 7 lines
Em Mon, Oct 19, 2015 at 04:54:47PM -0200, Arnaldo Carvalho de Melo escreveu:
Quoted 4 lines
Em Mon, Oct 19, 2015 at 07:34:46AM -0600, David Ahern escreveu:
Quoted 1 line
Seems like 'R' is more appropriate here.
Right, changed it.
And then, he does that on a later patch, duh.
Yeah, indeed - I messed that up: tried to introduce
__unusedbut noticed during development and testing on other distros that '__unused' is way too crowded a namespace (various fields in random headers are named like that), so after a bit of a fight with those headers I changed it back to__maybe_unused... but the original change slipped into the series.
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines
Do you want me to resend the series to fix this and the other problems David and you noticed?
No problem, I fixed it all already :-)
Please check my perf/core branch.
Looks good - thanks Arnaldo!
Ingo
tip-bot for Ingo Molnar
merge bot[tip:perf/core] perf bench mem: Rename 'routine' to 'routine_str'
In reply to Ingo Molnarperf bench mem: Rename 'routine' to 'routine_str'
Commit-ID: e815e327604af880bdcf38cdd711dfa78627ab2a Gitweb: http://git.kernel.org/tip/e815e327604af880bdcf38cdd711dfa78627ab2a Author: Ingo Molnar <[email protected]> AuthorDate: Mon, 19 Oct 2015 10:04:24 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Mon, 19 Oct 2015 16:05:27 -0300
perf bench mem: Rename 'routine' to 'routine_str'
So bench/mem-functions.c has a 'routine' name for the routines parameter string, but a 'length_str' name for the length parameter string.
We also have another entity named 'routine': 'struct routine'.
This is inconsistent and confusing: rename 'routine' to 'routine_str'.
Also fix typos in the --routine help text.
--- tools/perf/bench/mem-functions.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
tools/perf/bench/mem-functions.c +6 -6
@@ -24,7 +24,7 @@#define K 1024static const char *length_str ="1MB" ; -static const char *routine ="all" ; +static const char *routine_str ="all" ;static int iterations =1 ;static bool use_cycles;static int cycles_fd;
@@ -33,8 +33,8 @@ static const struct option options[] = {OPT_STRING ('l' ,"length" , &length_str,"1MB" ,"Specify length of memory to copy. " "Available units: B, KB, MB, GB and TB (upper and lower)" ), -OPT_STRING ('r' ,"routine" , &routine,"all" , -"Specify routine to copy, \"all\" runs all available routines" ), +OPT_STRING ('r' ,"routine" , &routine_str,"all" , +"Specify the routine to run, \"all\" runs all available routines" ),OPT_INTEGER ('i' ,"iterations" , &iterations,"repeat memcpy() invocation this number of times" ), OPT_BOOLEAN('c', "cycles", &use_cycles,
@@ -181,18 +181,18 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *return 1 ; } -if (!strncmp (routine,"all" ,3 )) { +if (!strncmp (routine_str,"all" ,3 )) {for (i =0 ; info->routines[i].name; i++)__bench_mem_routine (info, i, len, totallen);return 0 ; }for (i =0 ; info->routines[i].name; i++) { -if (!strcmp (info->routines[i].name, routine)) +if (!strcmp (info->routines[i].name, routine_str))break ; }if (!info->routines[i].name) { -printf ("Unknown routine:%s\n" , routine); +printf ("Unknown routine: %s\n" , routine_str);printf ("Available routines...\n" );for (i =0 ; info->routines[i].name; i++) { printf("\t%s ... %s\n",
PATCH 9/14 perf/bench/mem: Fix 'length' vs. 'size' naming confusion
In reply to Ingo MolnarSo 'perf bench mem memcpy/memset' consistently uses 'len' and 'length' for buffer sizes - while it's really a memory buffer size. (strings have length.)
Rename all affected variables.
--- tools/perf/bench/mem-functions.c | 92 ++++++++++++++++++++++++++++++------------------------------ 1 file changed, 46 insertions(+), 46 deletions(-)
tools/perf/bench/mem-functions.c +46 -46
@@ -23,15 +23,15 @@#define K 1024 -static const char *length_str ="1MB" ; +static const char *size_str ="1MB" ;static const char *routine_str ="all" ;static int iterations =1 ;static bool use_cycles;static int cycles_fd;static const struct option options[] = { -OPT_STRING ('l' ,"length" , &length_str,"1MB" , -"Specify length of memory to copy. " +OPT_STRING ('l' ,"size" , &size_str,"1MB" , +"Specify the size of the memory buffers. " "Available units: B, KB, MB, GB and TB (upper and lower)" ),OPT_STRING ('r' ,"routine" , &routine_str,"all" ,"Specify the routine to run, \"all\" runs all available routines" ),
@@ -117,12 +117,12 @@ static double timeval2double(struct timeval *ts)struct bench_mem_info {const struct routine *routines; -u64 (*do_cycles)(const struct routine *r,size_t len); -double (*do_gettimeofday)(const struct routine *r,size_t len); +u64 (*do_cycles)(const struct routine *r,size_t size); +double (*do_gettimeofday)(const struct routine *r,size_t size);const char *const *usage; }; -static void __bench_mem_routine (struct bench_mem_info *info,int r_idx,size_t len,double totallen) +static void __bench_mem_routine (struct bench_mem_info *info,int r_idx,size_t size,double size_total) {const struct routine *r = &info->routines[r_idx];double result_bps =0.0 ;
@@ -131,18 +131,18 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t lprintf ("routine %s (%s)\n" , r->name, r->desc);if (bench_format ==BENCH_FORMAT_DEFAULT ) -printf ("# Copying %s Bytes ...\n\n" , length_str); +printf ("# Copying %s Bytes ...\n\n" , size_str);if (use_cycles) { - result_cycles = info->do_cycles (r, len); + result_cycles = info->do_cycles (r, size); }else { - result_bps = info->do_gettimeofday (r, len); + result_bps = info->do_gettimeofday (r, size); }switch (bench_format) {case BENCH_FORMAT_DEFAULT :if (use_cycles) { -printf (" %14lf cycles/Byte\n" , (double )result_cycles/totallen); +printf (" %14lf cycles/Byte\n" , (double )result_cycles/size_total); }else {print_bps (result_bps); }
@@ -150,7 +150,7 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t lcase BENCH_FORMAT_SIMPLE :if (use_cycles) { -printf ("%lf\n" , (double )result_cycles/totallen); +printf ("%lf\n" , (double )result_cycles/size_total); }else {printf ("%lf\n" , result_bps); }
@@ -165,25 +165,25 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t lstatic int bench_mem_common (int argc,const char **argv,struct bench_mem_info *info) {int i; -size_t len; -double totallen; +size_t size; +double size_total; argc =parse_options (argc, argv, options, info->usage,0 );if (use_cycles)init_cycles (); - len = (size_t )perf_atoll ((char *)length_str); - totallen = (double )len * iterations; + size = (size_t )perf_atoll ((char *)size_str); + size_total = (double )size * iterations; -if ((s64 )len <=0 ) { -fprintf (stderr,"Invalid length:%s\n" , length_str); +if ((s64 )size <=0 ) { +fprintf (stderr,"Invalid size:%s\n" , size_str);return 1 ; }if (!strncmp (routine_str,"all" ,3 )) {for (i =0 ; info->routines[i].name; i++) -__bench_mem_routine (info, i, len, totallen); +__bench_mem_routine (info, i, size, size_total);return 0 ; }
@@ -201,43 +201,43 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *return 1 ; } -__bench_mem_routine (info, i, len, totallen); +__bench_mem_routine (info, i, size, size_total);return 0 ; } -static void memcpy_alloc_mem (void **dst,void **src,size_t length) +static void memcpy_alloc_mem (void **dst,void **src,size_t size) { - *dst =zalloc (length); + *dst =zalloc (size);if (!*dst) -die ("memory allocation failed - maybe length is too large?\n" ); +die ("memory allocation failed - maybe size is too large?\n" ); - *src =zalloc (length); + *src =zalloc (size);if (!*src) -die ("memory allocation failed - maybe length is too large?\n" ); +die ("memory allocation failed - maybe size is too large?\n" );/* Make sure to always prefault zero pages even if MMAP_THRESH is crossed: */ -memset (*src,0 , length); +memset (*src,0 , size); } -static u64 do_memcpy_cycles (const struct routine *r,size_t len) +static u64 do_memcpy_cycles (const struct routine *r,size_t size) {u64 cycle_start =0ULL , cycle_end =0ULL ;void *src =NULL , *dst =NULL ;memcpy_t fn = r->fn.memcpy;int i; -memcpy_alloc_mem (&dst, &src, len); +memcpy_alloc_mem (&dst, &src, size);/* * We prefault the freshly allocated memory range here, * to not measure page fault overhead: */ -fn (dst, src, len); +fn (dst, src, size); cycle_start =get_cycles ();for (i =0 ; i < iterations; ++i) -fn (dst, src, len); +fn (dst, src, size); cycle_end =get_cycles ();free (src);
@@ -245,24 +245,24 @@ static u64 do_memcpy_cycles(const struct routine *r, size_t len)return cycle_end - cycle_start; } -static double do_memcpy_gettimeofday (const struct routine *r,size_t len) +static double do_memcpy_gettimeofday (const struct routine *r,size_t size) {struct timeval tv_start, tv_end, tv_diff;memcpy_t fn = r->fn.memcpy;void *src =NULL , *dst =NULL ;int i; -memcpy_alloc_mem (&dst, &src, len); +memcpy_alloc_mem (&dst, &src, size);/* * We prefault the freshly allocated memory range here, * to not measure page fault overhead: */ -fn (dst, src, len); +fn (dst, src, size);BUG_ON (gettimeofday (&tv_start,NULL ));for (i =0 ; i < iterations; ++i) -fn (dst, src, len); +fn (dst, src, size);BUG_ON (gettimeofday (&tv_end,NULL ));timersub (&tv_end, &tv_start, &tv_diff);
@@ -270,7 +270,7 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t len)free (src);free (dst); -return (double )(((double )len * iterations) /timeval2double (&tv_diff)); +return (double )(((double )size * iterations) /timeval2double (&tv_diff)); }int bench_mem_memcpy (int argc,const char **argv,const char *prefix__maybe_unused )
@@ -285,61 +285,61 @@ int bench_mem_memcpy(int argc, const char **argv, const char *prefix __maybe_unureturn bench_mem_common (argc, argv, &info); } -static void memset_alloc_mem (void **dst,size_t length) +static void memset_alloc_mem (void **dst,size_t size) { - *dst =zalloc (length); + *dst =zalloc (size);if (!*dst) -die ("memory allocation failed - maybe length is too large?\n" ); +die ("memory allocation failed - maybe size is too large?\n" ); } -static u64 do_memset_cycles (const struct routine *r,size_t len) +static u64 do_memset_cycles (const struct routine *r,size_t size) {u64 cycle_start =0ULL , cycle_end =0ULL ;memset_t fn = r->fn.memset;void *dst =NULL ;int i; -memset_alloc_mem (&dst, len); +memset_alloc_mem (&dst, size);/* * We prefault the freshly allocated memory range here, * to not measure page fault overhead: */ -fn (dst,-1 , len); +fn (dst,-1 , size); cycle_start =get_cycles ();for (i =0 ; i < iterations; ++i) -fn (dst, i, len); +fn (dst, i, size); cycle_end =get_cycles ();free (dst);return cycle_end - cycle_start; } -static double do_memset_gettimeofday (const struct routine *r,size_t len) +static double do_memset_gettimeofday (const struct routine *r,size_t size) {struct timeval tv_start, tv_end, tv_diff;memset_t fn = r->fn.memset;void *dst =NULL ;int i; -memset_alloc_mem (&dst, len); +memset_alloc_mem (&dst, size);/* * We prefault the freshly allocated memory range here, * to not measure page fault overhead: */ -fn (dst,-1 , len); +fn (dst,-1 , size);BUG_ON (gettimeofday (&tv_start,NULL ));for (i =0 ; i < iterations; ++i) -fn (dst, i, len); +fn (dst, i, size);BUG_ON (gettimeofday (&tv_end,NULL ));timersub (&tv_end, &tv_start, &tv_diff);free (dst); -return (double )(((double )len * iterations) /timeval2double (&tv_diff)); +return (double )(((double )size * iterations) /timeval2double (&tv_diff)); }static const char *const bench_mem_memset_usage[] = {
Signature · 1 line
2.1.4
tip-bot for Ingo Molnar
merge bot[tip:perf/core] perf bench mem: Fix 'length' vs. 'size' naming confusion
perf bench mem: Fix 'length' vs. 'size' naming confusion
Commit-ID: a69b4f741340a52d0976636a45c9976a883f03a0 Gitweb: http://git.kernel.org/tip/a69b4f741340a52d0976636a45c9976a883f03a0 Author: Ingo Molnar <[email protected]> AuthorDate: Mon, 19 Oct 2015 10:04:25 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Mon, 19 Oct 2015 16:07:11 -0300
perf bench mem: Fix 'length' vs. 'size' naming confusion
So 'perf bench mem memcpy/memset' consistently uses 'len' and 'length' for buffer sizes - while it's really a memory buffer size. (strings have length.)
Rename all affected variables.
--- tools/perf/Documentation/perf-bench.txt | 8 +-- tools/perf/bench/mem-functions.c | 92 ++++++++++++++++----------------- 2 files changed, 50 insertions(+), 50 deletions(-)
tools/perf/Documentation/perf-bench.txt +4 -4
@@ -139,8 +139,8 @@ Suite for evaluating performance of simple memory copy in various ways. Options of *memcpy* ^^^^^^^^^^^^^^^^^^^ -l:: ---length:: -Specify length of memory to copy (default: 1MB). +--size:: +Specify size of memory to copy (default: 1MB). Available units are B, KB, MB, GB and TB (case insensitive). -r::
@@ -163,8 +163,8 @@ Suite for evaluating performance of simple memory set in various ways. Options of *memset* ^^^^^^^^^^^^^^^^^^^ -l:: ---length:: -Specify length of memory to set (default: 1MB). +--size:: +Specify size of memory to set (default: 1MB). Available units are B, KB, MB, GB and TB (case insensitive). -r::
tools/perf/bench/mem-functions.c +46 -46
258 lines not on this page · raw message
PATCH 10/14 perf/bench/mem: Improve user visible strings
In reply to Ingo Molnar - fix various typos in user visible output strings
- make the output consistent (wrt. capitalization and spelling)
- offer the list of routines to benchmark on '-r help'.
--- tools/perf/bench/mem-functions.c | 29 +++++++++++++++++------------ tools/perf/builtin-bench.c | 6 +++--- 2 files changed, 20 insertions(+), 15 deletions(-)
tools/perf/bench/mem-functions.c +17 -12
@@ -32,13 +32,17 @@ static int cycles_fd;static const struct option options[] = {OPT_STRING ('l' ,"size" , &size_str,"1MB" ,"Specify the size of the memory buffers. " -"Available units: B, KB, MB, GB and TB (upper and lower)" ), +"Available units: B, KB, MB, GB and TB (case insensitive)" ), +OPT_STRING ('r' ,"routine" , &routine_str,"all" , -"Specify the routine to run, \"all\" runs all available routines" ), +"Specify the routine to run, \"all\" runs all available routines, \"help\" lists them" ), +OPT_INTEGER ('i' ,"iterations" , &iterations, -"repeat memcpy() invocation this number of times" ), +"Repeat the function this number of times" ), +OPT_BOOLEAN ('c' ,"cycles" , &use_cycles,"Use a cycles event instead of gettimeofday() to measure performance" ), +OPT_END () };
@@ -106,13 +110,13 @@ static double timeval2double(struct timeval *ts)#define print_bps (x) do { \ if (x < K) \ - printf(" %14lf B/Sec\n", x); \ + printf(" %14lf bytes/sec\n", x); \ else if (x < K * K) \ - printf(" %14lfd KB/Sec\n", x / K); \ + printf(" %14lfd KB/sec\n", x / K); \ else if (x < K * K * K) \ - printf(" %14lf MB/Sec\n", x / K / K); \ + printf(" %14lf MB/sec\n", x / K / K); \ else \ - printf(" %14lf GB/Sec\n", x / K / K / K); \ + printf(" %14lf GB/sec\n", x / K / K / K); \ } while (0)struct bench_mem_info {
@@ -128,10 +132,10 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t sdouble result_bps =0.0 ;u64 result_cycles =0 ; -printf ("routine %s (%s)\n" , r->name, r->desc); +printf ("# Routine '%s' (%s)\n" , r->name, r->desc);if (bench_format ==BENCH_FORMAT_DEFAULT ) -printf ("# Copying %s Bytes ...\n\n" , size_str); +printf ("# Copying %s bytes ...\n\n" , size_str);if (use_cycles) { result_cycles = info->do_cycles (r, size);
@@ -142,7 +146,7 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t sswitch (bench_format) {case BENCH_FORMAT_DEFAULT :if (use_cycles) { -printf (" %14lf cycles/Byte\n" , (double )result_cycles/size_total); +printf (" %14lf cycles/byte\n" , (double )result_cycles/size_total); }else {print_bps (result_bps); }
@@ -192,8 +196,9 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *break ; }if (!info->routines[i].name) { -printf ("Unknown routine: %s\n" , routine_str); -printf ("Available routines...\n" ); +if (strcmp (routine_str,"help" ) &&strcmp (routine_str,"h" )) +printf ("Unknown routine: %s\n" , routine_str); +printf ("Available routines:\n" );for (i =0 ; info->routines[i].name; i++) {printf ("\t%s ... %s\n" , info->routines[i].name, info->routines[i].desc);
tools/perf/builtin-bench.c +3 -3
@@ -49,9 +49,9 @@ static struct bench sched_benchmarks[] = { };static struct bench mem_benchmarks[] = { - {"memcpy" ,"Benchmark for memcpy()" , bench_mem_memcpy }, - {"memset" ,"Benchmark for memset() tests" , bench_mem_memset }, - {"all" ,"Test all memory benchmarks" ,NULL }, + {"memcpy" ,"Benchmark for memcpy() functions" , bench_mem_memcpy }, + {"memset" ,"Benchmark for memset() functions" , bench_mem_memset }, + {"all" ,"Test all memory access benchmarks" ,NULL }, {NULL ,NULL ,NULL } };
Signature · 1 line
2.1.4
tip-bot for Ingo Molnar
merge bot[tip:perf/core] perf bench mem: Improve user visible strings
perf bench mem: Improve user visible strings
Commit-ID: 13b1fdce8d46027f346c0533a4323b58e2b5bad8 Gitweb: http://git.kernel.org/tip/13b1fdce8d46027f346c0533a4323b58e2b5bad8 Author: Ingo Molnar <[email protected]> AuthorDate: Mon, 19 Oct 2015 10:04:26 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Mon, 19 Oct 2015 16:07:18 -0300
perf bench mem: Improve user visible strings
- fix various typos in user visible output strings
- make the output consistent (wrt. capitalization and spelling)
- offer the list of routines to benchmark on '-r help'.
--- tools/perf/bench/mem-functions.c | 29 +++++++++++++++++------------ tools/perf/builtin-bench.c | 6 +++--- 2 files changed, 20 insertions(+), 15 deletions(-)
tools/perf/bench/mem-functions.c +17 -12
@@ -32,13 +32,17 @@ static int cycles_fd;static const struct option options[] = {OPT_STRING ('l' ,"size" , &size_str,"1MB" ,"Specify the size of the memory buffers. " -"Available units: B, KB, MB, GB and TB (upper and lower)" ), +"Available units: B, KB, MB, GB and TB (case insensitive)" ), +OPT_STRING ('r' ,"routine" , &routine_str,"all" , -"Specify the routine to run, \"all\" runs all available routines" ), +"Specify the routine to run, \"all\" runs all available routines, \"help\" lists them" ), +OPT_INTEGER ('i' ,"iterations" , &iterations, -"repeat memcpy() invocation this number of times" ), +"Repeat the function this number of times" ), +OPT_BOOLEAN ('c' ,"cycles" , &use_cycles,"Use a cycles event instead of gettimeofday() to measure performance" ), +OPT_END () };
@@ -106,13 +110,13 @@ static double timeval2double(struct timeval *ts)#define print_bps (x) do { \ if (x < K) \ - printf(" %14lf B/Sec\n", x); \ + printf(" %14lf bytes/sec\n", x); \ else if (x < K * K) \ - printf(" %14lfd KB/Sec\n", x / K); \ + printf(" %14lfd KB/sec\n", x / K); \ else if (x < K * K * K) \ - printf(" %14lf MB/Sec\n", x / K / K); \ + printf(" %14lf MB/sec\n", x / K / K); \ else \ - printf(" %14lf GB/Sec\n", x / K / K / K); \ + printf(" %14lf GB/sec\n", x / K / K / K); \ } while (0)struct bench_mem_info {
@@ -128,10 +132,10 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t sdouble result_bps =0.0 ;u64 result_cycles =0 ; -printf ("Routine %s (%s)\n" , r->name, r->desc); +printf ("# Routine '%s' (%s)\n" , r->name, r->desc);if (bench_format ==BENCH_FORMAT_DEFAULT ) -printf ("# Copying %s Bytes ...\n\n" , size_str); +printf ("# Copying %s bytes ...\n\n" , size_str);if (use_cycles) { result_cycles = info->do_cycles (r, size);
@@ -142,7 +146,7 @@ static void __bench_mem_routine(struct bench_mem_info *info, int r_idx, size_t sswitch (bench_format) {case BENCH_FORMAT_DEFAULT :if (use_cycles) { -printf (" %14lf cycles/Byte\n" , (double )result_cycles/size_total); +printf (" %14lf cycles/byte\n" , (double )result_cycles/size_total); }else {print_bps (result_bps); }
@@ -192,8 +196,9 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *break ; }if (!info->routines[i].name) { -printf ("Unknown routine: %s\n" , routine_str); -printf ("Available routines...\n" ); +if (strcmp (routine_str,"help" ) &&strcmp (routine_str,"h" )) +printf ("Unknown routine: %s\n" , routine_str); +printf ("Available routines:\n" );for (i =0 ; info->routines[i].name; i++) {printf ("\t%s ... %s\n" , info->routines[i].name, info->routines[i].desc);
tools/perf/builtin-bench.c +3 -3
@@ -49,9 +49,9 @@ static struct bench sched_benchmarks[] = { };static struct bench mem_benchmarks[] = { - {"memcpy" ,"Benchmark for memcpy()" , bench_mem_memcpy }, - {"memset" ,"Benchmark for memset() tests" , bench_mem_memset }, - {"all" ,"Test all memory benchmarks" ,NULL }, + {"memcpy" ,"Benchmark for memcpy() functions" , bench_mem_memcpy }, + {"memset" ,"Benchmark for memset() functions" , bench_mem_memset }, + {"all" ,"Test all memory access benchmarks" ,NULL }, {NULL ,NULL ,NULL } };
PATCH 11/14 perf/bench/mem: Reorganize the code a bit
In reply to Ingo MolnarReorder functions a bit, so that we synchronize the layout of the memcpy() and memset() portions of the code.
This improves the code, especially after we'll add an strlcpy() variant as well.
--- tools/perf/bench/mem-functions.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-)
tools/perf/bench/mem-functions.c +19 -19
@@ -58,25 +58,6 @@ struct routine { } fn; }; -struct routine memcpy_routines[] = { - { .name ="default" , - .desc ="Default memcpy() provided by glibc" , - .fn.memcpy = memcpy }, - -#ifdef HAVE_ARCH_X86_64_SUPPORT -# define MEMCPY_FN(_fn, _name, _desc) {.name = _name, .desc = _desc, .fn.memcpy = _fn}, -# include "mem-memcpy-x86-64-asm-def.h" -# undef MEMCPY_FN -#endif - - {NULL , } -}; - -static const char *const bench_mem_memcpy_usage[] = { -"perf bench mem memcpy <options>" , -NULL -}; -static struct perf_event_attr cycle_attr = { .type =PERF_TYPE_HARDWARE , .config =PERF_COUNT_HW_CPU_CYCLES
@@ -278,6 +259,25 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t size)return (double )(((double )size * iterations) /timeval2double (&tv_diff)); } +struct routine memcpy_routines[] = { + { .name ="default" , + .desc ="Default memcpy() provided by glibc" , + .fn.memcpy = memcpy }, + +#ifdef HAVE_ARCH_X86_64_SUPPORT +# define MEMCPY_FN(_fn, _name, _desc) {.name = _name, .desc = _desc, .fn.memcpy = _fn}, +# include "mem-memcpy-x86-64-asm-def.h" +# undef MEMCPY_FN +#endif + + {NULL , } +}; + +static const char *const bench_mem_memcpy_usage[] = { +"perf bench mem memcpy <options>" , +NULL +}; +int bench_mem_memcpy (int argc,const char **argv,const char *prefix__maybe_unused ) {struct bench_mem_info info = {
Signature · 1 line
2.1.4
tip-bot for Ingo Molnar
merge bot[tip:perf/core] perf bench mem: Reorganize the code a bit
perf bench mem: Reorganize the code a bit
Commit-ID: 5dd93304a5d386c73c0a59117752acdca67f857d Gitweb: http://git.kernel.org/tip/5dd93304a5d386c73c0a59117752acdca67f857d Author: Ingo Molnar <[email protected]> AuthorDate: Mon, 19 Oct 2015 10:04:27 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Mon, 19 Oct 2015 16:07:19 -0300
perf bench mem: Reorganize the code a bit
Reorder functions a bit, so that we synchronize the layout of the memcpy() and memset() portions of the code.
This improves the code, especially after we'll add an strlcpy() variant as well.
--- tools/perf/bench/mem-functions.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-)
tools/perf/bench/mem-functions.c +19 -19
@@ -58,25 +58,6 @@ struct routine { } fn; }; -struct routine memcpy_routines[] = { - { .name ="default" , - .desc ="Default memcpy() provided by glibc" , - .fn.memcpy = memcpy }, - -#ifdef HAVE_ARCH_X86_64_SUPPORT -# define MEMCPY_FN(_fn, _name, _desc) {.name = _name, .desc = _desc, .fn.memcpy = _fn}, -# include "mem-memcpy-x86-64-asm-def.h" -# undef MEMCPY_FN -#endif - - {NULL , } -}; - -static const char *const bench_mem_memcpy_usage[] = { -"perf bench mem memcpy <options>" , -NULL -}; -static struct perf_event_attr cycle_attr = { .type =PERF_TYPE_HARDWARE , .config =PERF_COUNT_HW_CPU_CYCLES
@@ -278,6 +259,25 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t size)return (double )(((double )size * iterations) /timeval2double (&tv_diff)); } +struct routine memcpy_routines[] = { + { .name ="default" , + .desc ="Default memcpy() provided by glibc" , + .fn.memcpy = memcpy }, + +#ifdef HAVE_ARCH_X86_64_SUPPORT +# define MEMCPY_FN(_fn, _name, _desc) {.name = _name, .desc = _desc, .fn.memcpy = _fn}, +# include "mem-memcpy-x86-64-asm-def.h" +# undef MEMCPY_FN +#endif + + {NULL , } +}; + +static const char *const bench_mem_memcpy_usage[] = { +"perf bench mem memcpy <options>" , +NULL +}; +int bench_mem_memcpy (int argc,const char **argv,const char *prefix__maybe_unused ) {struct bench_mem_info info = {
PATCH 12/14 perf/bench: Harmonize all the -l/--nr_loops options
In reply to Ingo MolnarWe have three benchmarking subsystems that specify some sort of 'number of loops' parameter - but all of them do it inconsistently:
numa: -l/--nr_loops
sched messaging: -l/--loops
mem memset/memcpy: -i/--iterations
Harmonize them to -l/--nr_loops by picking the numa variant - which is also the most likely one to have existing scripting which we don't want to break.
Plus improve the parameter help texts to indicate the default value for the nr_loops variable to keep users from guessing ...
Also propagate the naming to internal variables.
--- tools/perf/bench/mem-functions.c | 22 +++++++++++----------- tools/perf/bench/numa.c | 4 ++-- tools/perf/bench/sched-messaging.c | 10 +++++----- 3 files changed, 18 insertions(+), 18 deletions(-)
tools/perf/bench/mem-functions.c +11 -11
@@ -25,20 +25,20 @@static const char *size_str ="1MB" ;static const char *routine_str ="all" ; -static int iterations =1 ; +static int nr_loops =1 ;static bool use_cycles;static int cycles_fd;static const struct option options[] = { -OPT_STRING ('l' ,"size" , &size_str,"1MB" , +OPT_STRING ('s' ,"size" , &size_str,"1MB" ,"Specify the size of the memory buffers. " "Available units: B, KB, MB, GB and TB (case insensitive)" ),OPT_STRING ('r' ,"routine" , &routine_str,"all" ,"Specify the routine to run, \"all\" runs all available routines, \"help\" lists them" ), -OPT_INTEGER ('i' ,"iterations" , &iterations, -"Repeat the function this number of times" ), +OPT_INTEGER ('l' ,"nr_loops" , &nr_loops, +"Specify the number of loops to run. (default: 1)" ),OPT_BOOLEAN ('c' ,"cycles" , &use_cycles,"Use a cycles event instead of gettimeofday() to measure performance" ),
@@ -159,7 +159,7 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *init_cycles (); size = (size_t )perf_atoll ((char *)size_str); - size_total = (double )size * iterations; + size_total = (double )size * nr_loops;if ((s64 )size <=0 ) {fprintf (stderr,"Invalid size:%s\n" , size_str);
@@ -222,7 +222,7 @@ static u64 do_memcpy_cycles(const struct routine *r, size_t size)fn (dst, src, size); cycle_start =get_cycles (); -for (i =0 ; i < iterations; ++i) +for (i =0 ; i < nr_loops; ++i)fn (dst, src, size); cycle_end =get_cycles ();
@@ -247,7 +247,7 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t size)fn (dst, src, size);BUG_ON (gettimeofday (&tv_start,NULL )); -for (i =0 ; i < iterations; ++i) +for (i =0 ; i < nr_loops; ++i)fn (dst, src, size);BUG_ON (gettimeofday (&tv_end,NULL ));
@@ -256,7 +256,7 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t size)free (src);free (dst); -return (double )(((double )size * iterations) /timeval2double (&tv_diff)); +return (double )(((double )size * nr_loops) /timeval2double (&tv_diff)); }struct routine memcpy_routines[] = {
@@ -313,7 +313,7 @@ static u64 do_memset_cycles(const struct routine *r, size_t size)fn (dst,-1 , size); cycle_start =get_cycles (); -for (i =0 ; i < iterations; ++i) +for (i =0 ; i < nr_loops; ++i)fn (dst, i, size); cycle_end =get_cycles ();
@@ -337,14 +337,14 @@ static double do_memset_gettimeofday(const struct routine *r, size_t size)fn (dst,-1 , size);BUG_ON (gettimeofday (&tv_start,NULL )); -for (i =0 ; i < iterations; ++i) +for (i =0 ; i < nr_loops; ++i)fn (dst, i, size);BUG_ON (gettimeofday (&tv_end,NULL ));timersub (&tv_end, &tv_start, &tv_diff);free (dst); -return (double )(((double )size * iterations) /timeval2double (&tv_diff)); +return (double )(((double )size * nr_loops) /timeval2double (&tv_diff)); }static const char *const bench_mem_memset_usage[] = {
tools/perf/bench/numa.c +2 -2
@@ -164,8 +164,8 @@ static const struct option options[] = {OPT_STRING ('L' ,"mb_proc_locked" , &p0.mb_proc_locked_str,"MB" ,"process serialized/locked memory access (MBs), <= process_memory" ),OPT_STRING ('T' ,"mb_thread" , &p0.mb_thread_str,"MB" ,"thread memory (MBs)" ), -OPT_UINTEGER ('l' ,"nr_loops" , &p0.nr_loops,"max number of loops to run" ), -OPT_UINTEGER ('s' ,"nr_secs" , &p0.nr_secs,"max number of seconds to run" ), +OPT_UINTEGER ('l' ,"nr_loops" , &p0.nr_loops,"max number of loops to run (default: unlimited)" ), +OPT_UINTEGER ('s' ,"nr_secs" , &p0.nr_secs,"max number of seconds to run (default: 5 secs)" ),OPT_UINTEGER ('u' ,"usleep" , &p0.sleep_usecs,"usecs to sleep per loop iteration" ), OPT_BOOLEAN('R', "data_reads" , &p0.data_reads, "access the data via writes (can be mixed with -W)"),
tools/perf/bench/sched-messaging.c +5 -5
@@ -33,7 +33,7 @@#define DATASIZE 100static bool use_pipes = false; -static unsigned int loops =100 ; +static unsigned int nr_loops =100 ;static bool thread_mode = false;static unsigned int num_groups =10 ;
@@ -79,7 +79,7 @@ static void ready(int ready_out, int wakefd)err (EXIT_FAILURE ,"poll" ); } -/* Sender sprays loops messages down each file descriptor */ +/* Sender sprays nr_loops messages down each file descriptor */ static void *sender (struct sender_context *ctx) {char data[DATASIZE ];
@@ -88,7 +88,7 @@ static void *sender(struct sender_context *ctx)ready (ctx->ready_out, ctx->wakefd);/* Now pump to every receiver. */ -for (i =0 ; i < loops; i++) { +for (i =0 ; i < nr_loops; i++) {for (j =0 ; j < ctx->num_fds; j++) {int ret, done =0 ;
@@ -213,7 +213,7 @@ static unsigned int group(pthread_t *pth,/* Create the pipe between client and server */ fdpair (fds); - ctx->num_packets = num_fds * loops; + ctx->num_packets = num_fds * nr_loops; ctx->in_fds[0 ] = fds[0 ]; ctx->in_fds[1 ] = fds[1 ]; ctx->ready_out = ready_out;
@@ -250,7 +250,7 @@ static const struct option options[] = {OPT_BOOLEAN ('t' ,"thread" , &thread_mode,"Be multi thread instead of multi process" ),OPT_UINTEGER ('g' ,"group" , &num_groups,"Specify number of groups" ), -OPT_UINTEGER ('l' ,"loop" , &loops,"Specify number of loops" ), +OPT_UINTEGER ('l' ,"nr_loops" , &nr_loops,"Specify the number of loops to run (default: 100)" ), OPT_END() };
Signature · 1 line
2.1.4
tip-bot for Ingo Molnar
merge bot[tip:perf/core] perf bench: Harmonize all the -l/ --nr_loops options
perf bench: Harmonize all the -l/--nr_loops options
Commit-ID: b0d22e52e3d2c2b151dfaa0f6e01bafa5475344f Gitweb: http://git.kernel.org/tip/b0d22e52e3d2c2b151dfaa0f6e01bafa5475344f Author: Ingo Molnar <[email protected]> AuthorDate: Mon, 19 Oct 2015 10:04:28 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Mon, 19 Oct 2015 16:10:05 -0300
perf bench: Harmonize all the -l/--nr_loops options
We have three benchmarking subsystems that specify some sort of 'number of loops' parameter - but all of them do it inconsistently:
numa: -l/--nr_loops
sched messaging: -l/--loops
mem memset/memcpy: -i/--iterations
Harmonize them to -l/--nr_loops by picking the numa variant - which is also the most likely one to have existing scripting which we don't want to break.
Plus improve the parameter help texts to indicate the default value for the nr_loops variable to keep users from guessing ...
Also propagate the naming to internal variables.
--- tools/perf/Documentation/perf-bench.txt | 10 +++++----- tools/perf/bench/mem-functions.c | 22 +++++++++++----------- tools/perf/bench/numa.c | 4 ++-- tools/perf/bench/sched-messaging.c | 10 +++++----- 4 files changed, 23 insertions(+), 23 deletions(-)
tools/perf/Documentation/perf-bench.txt +5 -5
@@ -82,7 +82,7 @@ Be multi thread instead of multi process Specify number of groups -l:: ---loop=:: +--nr_loops=:: Specify number of loops Example of *messaging*
@@ -149,8 +149,8 @@ Specify routine to copy (default: default). Available routines are depend on the architecture. On x86-64, x86-64-unrolled, x86-64-movsq and x86-64-movsb are supported. --i:: ---iterations:: +-l:: +--nr_loops:: Repeat memcpy invocation this number of times. -c::
@@ -173,8 +173,8 @@ Specify routine to set (default: default). Available routines are depend on the architecture. On x86-64, x86-64-unrolled, x86-64-stosq and x86-64-stosb are supported. --i:: ---iterations:: +-l:: +--nr_loops:: Repeat memset invocation this number of times. -c::
tools/perf/bench/mem-functions.c +11 -11
@@ -25,20 +25,20 @@static const char *size_str ="1MB" ;static const char *routine_str ="all" ; -static int iterations =1 ; +static int nr_loops =1 ;static bool use_cycles;static int cycles_fd;static const struct option options[] = { -OPT_STRING ('l' ,"size" , &size_str,"1MB" , +OPT_STRING ('s' ,"size" , &size_str,"1MB" ,"Specify the size of the memory buffers. " "Available units: B, KB, MB, GB and TB (case insensitive)" ),OPT_STRING ('r' ,"routine" , &routine_str,"all" ,"Specify the routine to run, \"all\" runs all available routines, \"help\" lists them" ), -OPT_INTEGER ('i' ,"iterations" , &iterations, -"Repeat the function this number of times" ), +OPT_INTEGER ('l' ,"nr_loops" , &nr_loops, +"Specify the number of loops to run. (default: 1)" ),OPT_BOOLEAN ('c' ,"cycles" , &use_cycles,"Use a cycles event instead of gettimeofday() to measure performance" ),
@@ -159,7 +159,7 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *init_cycles (); size = (size_t )perf_atoll ((char *)size_str); - size_total = (double )size * iterations; + size_total = (double )size * nr_loops;if ((s64 )size <=0 ) {fprintf (stderr,"Invalid size:%s\n" , size_str);
@@ -222,7 +222,7 @@ static u64 do_memcpy_cycles(const struct routine *r, size_t size)fn (dst, src, size); cycle_start =get_cycles (); -for (i =0 ; i < iterations; ++i) +for (i =0 ; i < nr_loops; ++i)fn (dst, src, size); cycle_end =get_cycles ();
@@ -247,7 +247,7 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t size)fn (dst, src, size);BUG_ON (gettimeofday (&tv_start,NULL )); -for (i =0 ; i < iterations; ++i) +for (i =0 ; i < nr_loops; ++i)fn (dst, src, size);BUG_ON (gettimeofday (&tv_end,NULL ));
@@ -256,7 +256,7 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t size)free (src);free (dst); -return (double )(((double )size * iterations) /timeval2double (&tv_diff)); +return (double )(((double )size * nr_loops) /timeval2double (&tv_diff)); }struct routine memcpy_routines[] = {
@@ -313,7 +313,7 @@ static u64 do_memset_cycles(const struct routine *r, size_t size)fn (dst,-1 , size); cycle_start =get_cycles (); -for (i =0 ; i < iterations; ++i) +for (i =0 ; i < nr_loops; ++i)fn (dst, i, size); cycle_end =get_cycles ();
@@ -337,14 +337,14 @@ static double do_memset_gettimeofday(const struct routine *r, size_t size)fn (dst,-1 , size);BUG_ON (gettimeofday (&tv_start,NULL )); -for (i =0 ; i < iterations; ++i) +for (i =0 ; i < nr_loops; ++i)fn (dst, i, size);BUG_ON (gettimeofday (&tv_end,NULL ));timersub (&tv_end, &tv_start, &tv_diff);free (dst); -return (double )(((double )size * iterations) /timeval2double (&tv_diff)); +return (double )(((double )size * nr_loops) /timeval2double (&tv_diff)); }static const char *const bench_mem_memset_usage[] = {
tools/perf/bench/numa.c +2 -2
@@ -164,8 +164,8 @@ static const struct option options[] = {OPT_STRING ('L' ,"mb_proc_locked" , &p0.mb_proc_locked_str,"MB" ,"process serialized/locked memory access (MBs), <= process_memory" ),OPT_STRING ('T' ,"mb_thread" , &p0.mb_thread_str,"MB" ,"thread memory (MBs)" ), -OPT_UINTEGER ('l' ,"nr_loops" , &p0.nr_loops,"max number of loops to run" ), -OPT_UINTEGER ('s' ,"nr_secs" , &p0.nr_secs,"max number of seconds to run" ), +OPT_UINTEGER ('l' ,"nr_loops" , &p0.nr_loops,"max number of loops to run (default: unlimited)" ), +OPT_UINTEGER ('s' ,"nr_secs" , &p0.nr_secs,"max number of seconds to run (default: 5 secs)" ),OPT_UINTEGER ('u' ,"usleep" , &p0.sleep_usecs,"usecs to sleep per loop iteration" ), OPT_BOOLEAN('R', "data_reads" , &p0.data_reads, "access the data via writes (can be mixed with -W)"),
tools/perf/bench/sched-messaging.c +5 -5
@@ -33,7 +33,7 @@#define DATASIZE 100static bool use_pipes = false; -static unsigned int loops =100 ; +static unsigned int nr_loops =100 ;static bool thread_mode = false;static unsigned int num_groups =10 ;
@@ -79,7 +79,7 @@ static void ready(int ready_out, int wakefd)err (EXIT_FAILURE ,"poll" ); } -/* Sender sprays loops messages down each file descriptor */ +/* Sender sprays nr_loops messages down each file descriptor */ static void *sender (struct sender_context *ctx) {char data[DATASIZE ];
@@ -88,7 +88,7 @@ static void *sender(struct sender_context *ctx)ready (ctx->ready_out, ctx->wakefd);/* Now pump to every receiver. */ -for (i =0 ; i < loops; i++) { +for (i =0 ; i < nr_loops; i++) {for (j =0 ; j < ctx->num_fds; j++) {int ret, done =0 ;
@@ -213,7 +213,7 @@ static unsigned int group(pthread_t *pth,/* Create the pipe between client and server */ fdpair (fds); - ctx->num_packets = num_fds * loops; + ctx->num_packets = num_fds * nr_loops; ctx->in_fds[0 ] = fds[0 ]; ctx->in_fds[1 ] = fds[1 ]; ctx->ready_out = ready_out;
@@ -250,7 +250,7 @@ static const struct option options[] = {OPT_BOOLEAN ('t' ,"thread" , &thread_mode,"Be multi thread instead of multi process" ),OPT_UINTEGER ('g' ,"group" , &num_groups,"Specify number of groups" ), -OPT_UINTEGER ('l' ,"loop" , &loops,"Specify number of loops" ), +OPT_UINTEGER ('l' ,"nr_loops" , &nr_loops,"Specify the number of loops to run (default: 100)" ), OPT_END() };
PATCH 13/14 perf/bench/mem: Rename 'routine' to 'function'
In reply to Ingo MolnarSo right now there's a somewhat inconsistent mess of the benchmarking code and options sometimes calling benchmarked functions 'functions', sometimes calling them 'routines'.
Name them 'functions' consistently.
--- tools/perf/bench/mem-functions.c | 60 ++++++++++++++++++++++++++++++------------------------------ 1 file changed, 30 insertions(+), 30 deletions(-)
tools/perf/bench/mem-functions.c +30 -30
@@ -24,7 +24,7 @@#define K 1024static const char *size_str ="1MB" ; -static const char *routine_str ="all" ; +static const char *function_str ="all" ;static int nr_loops =1 ;static bool use_cycles;static int cycles_fd;
@@ -34,8 +34,8 @@ static const struct option options[] = {"Specify the size of the memory buffers. " "Available units: B, KB, MB, GB and TB (case insensitive)"), -OPT_STRING ('r' ,"routine" , &routine_str,"all" , -"Specify the routine to run, \"all\" runs all available routines, \"help\" lists them" ), +OPT_STRING ('f' ,"function" , &function_str,"all" , +"Specify the function to run, \"all\" runs all available functions, \"help\" lists them" ),OPT_INTEGER ('l' ,"nr_loops" , &nr_loops, "Specify the number of loops to run. (default: 1)"),
@@ -49,7 +49,7 @@ static const struct option options[] = {typedef void *(*memcpy_t )(void *,const void *,size_t );typedef void *(*memset_t )(void *,int ,size_t ); -struct routine { +struct function {const char *name;const char *desc;union {
@@ -101,19 +101,19 @@ static double timeval2double(struct timeval *ts) }while (0 ) struct bench_mem_info { -const struct routine *routines; -u64 (*do_cycles)(const struct routine *r,size_t size); -double (*do_gettimeofday)(const struct routine *r,size_t size); +const struct function *functions; +u64 (*do_cycles)(const struct function *r,size_t size); +double (*do_gettimeofday)(const struct function *r,size_t size);const char *const *usage; }; -static void __bench_mem_routine (struct bench_mem_info *info,int r_idx,size_t size,double size_total) +static void __bench_mem_function (struct bench_mem_info *info,int r_idx,size_t size,double size_total) { -const struct routine *r = &info->routines[r_idx]; +const struct function *r = &info->functions[r_idx];double result_bps =0.0 ;u64 result_cycles =0 ; -printf ("# Routine '%s' (%s)\n" , r->name, r->desc); +printf ("# function '%s' (%s)\n" , r->name, r->desc);if (bench_format ==BENCH_FORMAT_DEFAULT )printf ("# Copying %s bytes ...\n\n" , size_str);
@@ -166,28 +166,28 @@ static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *return 1 ; } -if (!strncmp (routine_str,"all" ,3 )) { -for (i =0 ; info->routines[i].name; i++) -__bench_mem_routine (info, i, size, size_total); +if (!strncmp (function_str,"all" ,3 )) { +for (i =0 ; info->functions[i].name; i++) +__bench_mem_function (info, i, size, size_total);return 0 ; } -for (i =0 ; info->routines[i].name; i++) { -if (!strcmp (info->routines[i].name, routine_str)) +for (i =0 ; info->functions[i].name; i++) { +if (!strcmp (info->functions[i].name, function_str))break ; } -if (!info->routines[i].name) { -if (strcmp (routine_str,"help" ) &&strcmp (routine_str,"h" )) -printf ("Unknown routine: %s\n" , routine_str); -printf ("Available routines:\n" ); -for (i =0 ; info->routines[i].name; i++) { +if (!info->functions[i].name) { +if (strcmp (function_str,"help" ) &&strcmp (function_str,"h" )) +printf ("Unknown function: %s\n" , function_str); +printf ("Available functions:\n" ); +for (i =0 ; info->functions[i].name; i++) {printf ("\t%s ... %s\n" , - info->routines[i].name, info->routines[i].desc); + info->functions[i].name, info->functions[i].desc); }return 1 ; } -__bench_mem_routine (info, i, size, size_total); +__bench_mem_function (info, i, size, size_total);return 0 ; }
@@ -206,7 +206,7 @@ static void memcpy_alloc_mem(void **dst, void **src, size_t size)memset (*src,0 , size); } -static u64 do_memcpy_cycles (const struct routine *r,size_t size) +static u64 do_memcpy_cycles (const struct function *r,size_t size) {u64 cycle_start =0ULL , cycle_end =0ULL ;void *src =NULL , *dst =NULL ;
@@ -231,7 +231,7 @@ static u64 do_memcpy_cycles(const struct routine *r, size_t size)return cycle_end - cycle_start; } -static double do_memcpy_gettimeofday (const struct routine *r,size_t size) +static double do_memcpy_gettimeofday (const struct function *r,size_t size) {struct timeval tv_start, tv_end, tv_diff;memcpy_t fn = r->fn.memcpy;
@@ -259,7 +259,7 @@ static double do_memcpy_gettimeofday(const struct routine *r, size_t size)return (double )(((double )size * nr_loops) /timeval2double (&tv_diff)); } -struct routine memcpy_routines[] = { +struct function memcpy_functions[] = { { .name ="default" , .desc ="Default memcpy() provided by glibc" , .fn.memcpy = memcpy },
@@ -281,7 +281,7 @@ static const char * const bench_mem_memcpy_usage[] = {int bench_mem_memcpy (int argc,const char **argv,const char *prefix__maybe_unused ) {struct bench_mem_info info = { - .routines = memcpy_routines, + .functions = memcpy_functions, .do_cycles = do_memcpy_cycles, .do_gettimeofday = do_memcpy_gettimeofday, .usage = bench_mem_memcpy_usage,
@@ -297,7 +297,7 @@ static void memset_alloc_mem(void **dst, size_t size)die ("memory allocation failed - maybe size is too large?\n" ); } -static u64 do_memset_cycles (const struct routine *r,size_t size) +static u64 do_memset_cycles (const struct function *r,size_t size) {u64 cycle_start =0ULL , cycle_end =0ULL ;memset_t fn = r->fn.memset;
@@ -321,7 +321,7 @@ static u64 do_memset_cycles(const struct routine *r, size_t size)return cycle_end - cycle_start; } -static double do_memset_gettimeofday (const struct routine *r,size_t size) +static double do_memset_gettimeofday (const struct function *r,size_t size) {struct timeval tv_start, tv_end, tv_diff;memset_t fn = r->fn.memset;
@@ -352,7 +352,7 @@ static const char * const bench_mem_memset_usage[] = {NULL }; -static const struct routine memset_routines[] = { +static const struct function memset_functions[] = { { .name ="default" , .desc ="Default memset() provided by glibc" , .fn.memset = memset },
@@ -369,7 +369,7 @@ static const struct routine memset_routines[] = {int bench_mem_memset (int argc,const char **argv,const char *prefix__maybe_unused ) {struct bench_mem_info info = { - .routines = memset_routines, + .functions = memset_functions, .do_cycles = do_memset_cycles, .do_gettimeofday = do_memset_gettimeofday, .usage = bench_mem_memset_usage,
Signature · 1 line
2.1.4
tip-bot for Ingo Molnar
merge bot[tip:perf/core] perf bench mem: Rename 'routine' to 'function'
perf bench mem: Rename 'routine' to 'function'
Commit-ID: 2f211c84ad40469c15226e899b720624fbd28e20 Gitweb: http://git.kernel.org/tip/2f211c84ad40469c15226e899b720624fbd28e20 Author: Ingo Molnar <[email protected]> AuthorDate: Mon, 19 Oct 2015 10:04:29 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Mon, 19 Oct 2015 16:10:25 -0300
perf bench mem: Rename 'routine' to 'function'
So right now there's a somewhat inconsistent mess of the benchmarking code and options sometimes calling benchmarked functions 'functions', sometimes calling them 'routines'.
Name them 'functions' consistently.
--- tools/perf/Documentation/perf-bench.txt | 16 ++++----- tools/perf/bench/mem-functions.c | 60 ++++++++++++++++----------------- 2 files changed, 38 insertions(+), 38 deletions(-)
tools/perf/Documentation/perf-bench.txt +8 -8
@@ -143,10 +143,10 @@ Options of *memcpy* Specify size of memory to copy (default: 1MB). Available units are B, KB, MB, GB and TB (case insensitive). --r:: ---routine:: -Specify routine to copy (default: default). -Available routines are depend on the architecture. +-f:: +--function:: +Specify function to copy (default: default). +Available functions are depend on the architecture. On x86-64, x86-64-unrolled, x86-64-movsq and x86-64-movsb are supported. -l::
@@ -167,10 +167,10 @@ Options of *memset* Specify size of memory to set (default: 1MB). Available units are B, KB, MB, GB and TB (case insensitive). --r:: ---routine:: -Specify routine to set (default: default). -Available routines are depend on the architecture. +-f:: +--function:: +Specify function to set (default: default). +Available functions are depend on the architecture. On x86-64, x86-64-unrolled, x86-64-stosq and x86-64-stosb are supported. -l::
tools/perf/bench/mem-functions.c +30 -30
155 lines not on this page · raw message
PATCH 14/14 perf/bench: Run benchmarks, don't test them
In reply to Ingo MolnarSo right now we output this text:
memcpy: Benchmark for memcpy() functions
memset: Benchmark for memset() functions
all: Test all memory access benchmarks
But the right verb to use with benchmarks is to 'run' them, not 'test' them.
So change this (and all similar texts) to:
memcpy: Benchmark for memcpy() functions
memset: Benchmark for memset() functions
all: Run all memory access benchmarks
--- tools/perf/builtin-bench.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
tools/perf/builtin-bench.c +4 -4
@@ -36,7 +36,7 @@ struct bench {#ifdef HAVE_LIBNUMA_SUPPORT static struct bench numa_benchmarks[] = { {"mem" ,"Benchmark for NUMA workloads" , bench_numa }, - {"all" ,"Test all NUMA benchmarks" ,NULL }, + {"all" ,"Run all NUMA benchmarks" ,NULL }, {NULL ,NULL ,NULL } };#endif
@@ -44,14 +44,14 @@ static struct bench numa_benchmarks[] = {static struct bench sched_benchmarks[] = { {"messaging" ,"Benchmark for scheduling and IPC" , bench_sched_messaging }, {"pipe" ,"Benchmark for pipe() between two processes" , bench_sched_pipe }, - {"all" ,"Test all scheduler benchmarks" ,NULL }, + {"all" ,"Run all scheduler benchmarks" ,NULL }, {NULL ,NULL ,NULL } };static struct bench mem_benchmarks[] = { {"memcpy" ,"Benchmark for memcpy() functions" , bench_mem_memcpy }, {"memset" ,"Benchmark for memset() functions" , bench_mem_memset }, - {"all" ,"Test all memory access benchmarks" ,NULL }, + {"all" ,"Run all memory access benchmarks" ,NULL }, {NULL ,NULL ,NULL } };
@@ -62,7 +62,7 @@ static struct bench futex_benchmarks[] = { { "requeue", "Benchmark for futex requeue calls", bench_futex_requeue },/* pi-futexes */ { "lock-pi", "Benchmark for futex lock_pi calls", bench_futex_lock_pi }, - { "all", "Test all futex benchmarks", NULL }, + { "all", "Run all futex benchmarks", NULL }, { NULL, NULL, NULL } };
Signature · 1 line
2.1.4
tip-bot for Ingo Molnar
merge bot[tip:perf/core] perf bench: Run benchmarks, don't test them
perf bench: Run benchmarks, don't test them
Commit-ID: aa254af25c40d6d1cdc3f354db29eaf3e85a5ede Gitweb: http://git.kernel.org/tip/aa254af25c40d6d1cdc3f354db29eaf3e85a5ede Author: Ingo Molnar <[email protected]> AuthorDate: Mon, 19 Oct 2015 10:04:30 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Mon, 19 Oct 2015 16:10:25 -0300
perf bench: Run benchmarks, don't test them
So right now we output this text:
memcpy: Benchmark for memcpy() functions
memset: Benchmark for memset() functions
all: Test all memory access benchmarks
But the right verb to use with benchmarks is to 'run' them, not 'test' them.
So change this (and all similar texts) to:
memcpy: Benchmark for memcpy() functions
memset: Benchmark for memset() functions
all: Run all memory access benchmarks
--- tools/perf/builtin-bench.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
tools/perf/builtin-bench.c +4 -4
@@ -36,7 +36,7 @@ struct bench {#ifdef HAVE_LIBNUMA_SUPPORT static struct bench numa_benchmarks[] = { {"mem" ,"Benchmark for NUMA workloads" , bench_numa }, - {"all" ,"Test all NUMA benchmarks" ,NULL }, + {"all" ,"Run all NUMA benchmarks" ,NULL }, {NULL ,NULL ,NULL } };#endif
@@ -44,14 +44,14 @@ static struct bench numa_benchmarks[] = {static struct bench sched_benchmarks[] = { {"messaging" ,"Benchmark for scheduling and IPC" , bench_sched_messaging }, {"pipe" ,"Benchmark for pipe() between two processes" , bench_sched_pipe }, - {"all" ,"Test all scheduler benchmarks" ,NULL }, + {"all" ,"Run all scheduler benchmarks" ,NULL }, {NULL ,NULL ,NULL } };static struct bench mem_benchmarks[] = { {"memcpy" ,"Benchmark for memcpy() functions" , bench_mem_memcpy }, {"memset" ,"Benchmark for memset() functions" , bench_mem_memset }, - {"all" ,"Test all memory access benchmarks" ,NULL }, + {"all" ,"Run all memory access benchmarks" ,NULL }, {NULL ,NULL ,NULL } };
@@ -62,7 +62,7 @@ static struct bench futex_benchmarks[] = { { "requeue", "Benchmark for futex requeue calls", bench_futex_requeue },/* pi-futexes */ { "lock-pi", "Benchmark for futex lock_pi calls", bench_futex_lock_pi }, - { "all", "Test all futex benchmarks", NULL }, + { "all", "Run all futex benchmarks", NULL }, { NULL, NULL, NULL } };
Quoted 10 lines · Ingo Molnar
tools/perf/bench/Build | 2 +- tools/perf/bench/mem-functions.c | 379 +++++++++++++++++++++++++++++++++++++++++++++++++ tools/perf/bench/mem-memcpy.c | 434 --------------------------------------------------------- tools/perf/bench/numa.c | 4 +- tools/perf/bench/sched-messaging.c | 10 +- tools/perf/builtin-bench.c | 14 +- 6 files changed, 394 insertions(+), 449 deletions(-)create mode 100644
tools/perf/bench/mem-functions.cdelete mode 100644tools/perf/bench/mem-memcpy.c
tools/perf/Documentation needs updating for the user visible options.
Em Mon, Oct 19, 2015 at 07:40:36AM -0600, David Ahern escreveu:
Quoted 13 lines · Ingo Molnar
Quoted 11 lines
tools/perf/bench/Build | 2 +- tools/perf/bench/mem-functions.c | 379 +++++++++++++++++++++++++++++++++++++++++++++++++ tools/perf/bench/mem-memcpy.c | 434 --------------------------------------------------------- tools/perf/bench/numa.c | 4 +- tools/perf/bench/sched-messaging.c | 10 +- tools/perf/builtin-bench.c | 14 +- 6 files changed, 394 insertions(+), 449 deletions(-) create mode 100644 tools/perf/bench/mem-functions.c delete mode 100644 tools/perf/bench/mem-memcpy.c
Quoted 1 line
tools/perf/Documentationneeds updating for the user visible options.
perf bench mem: Rename 'routine' to 'function'
changes -r to -f, fixed. Looking at the others...