perf/core improvements and fixes
Arnaldo Carvalho de Melo
maintainerHi Ingo,
Please consider pulling,
- Arnaldo
The following changes since commit e9363deeb286e916353f11b11d1f351c6ff54082:
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core (2015-10-14 15:06:33 +0200)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-core-for-mingo
for you to fetch changes up to a4c6a3e8bbb675a601f529881c51ff226f83c3f1:
perf bench: Use named initializers in the trailer too (2015-10-19 18:17:25 -0300)
----------------------------------------------------------------
perf/core improvements and fixes:
User visible:
- 'perf bench mem' now prefaults unconditionally, no sense in providing modes where page faults are measured (Ingo Molnar)
- Harmonize -l/--nr_loops accross 'perf bench' (Ingo Molnar)
- Various 'perf bench' consistency improvements (Ingo Molnar)
- Suppress libtraceevent warnings in non-verbose 'perf test' mode (Namhyung Kim)
- Move some tracepoint event test error messages to the verbose mode of 'perf test' (Namhyung Kim)
- Make 'perf help' usage message consistent with other tools (Yunlong Song)
Build fixes:
- Fix 'perf bench' build with gcc 4.4.7 (Arnaldo Carvalho de Melo)
Infrastructure:
- 'perf stat' prep work for the 'perf stat scripting' patchkit (Jiri Olsa)
----------------------------------------------------------------
Arnaldo Carvalho de Melo (1):
perf bench: Use named initializers in the trailer too
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
Jiri Olsa (5):
perf stat: Rename perf_stat struct into perf_stat_evsel perf stat: Add AGGR_UNSET mode
perf cpu_map: Make cpu_map__build_map global perf cpu_map: Add data arg to cpu_map__build_map callback perf script: Check output fields only for samples
Namhyung Kim (2):
perf test: Silence tracepoint event failures perf test: Suppress libtraceevent warnings
Yunlong Song (1):
perf help: Change 'usage' to 'Usage' for consistency
tools/perf/Documentation/perf-bench.txt | 54 ++-- 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 +- tools/perf/builtin-help.c | 2 +- tools/perf/builtin-script.c | 5 +- tools/perf/builtin-stat.c | 23 +- tools/perf/tests/openat-syscall-all-cpus.c | 2 +- tools/perf/tests/openat-syscall-tp-fields.c | 2 +- tools/perf/tests/openat-syscall.c | 2 +- tools/perf/tests/parse-events.c | 14 + tools/perf/tests/topology.c | 4 +- tools/perf/util/cpumap.c | 17 +- tools/perf/util/cpumap.h | 7 +- tools/perf/util/parse-options.c | 4 +- tools/perf/util/stat.c | 13 +- tools/perf/util/stat.h | 3 +- tools/perf/util/usage.c | 5 + tools/perf/util/util.h | 1 + 22 files changed, 487 insertions(+), 514 deletions(-) create mode 100644 tools/perf/bench/mem-functions.c delete mode 100644 tools/perf/bench/mem-memcpy.c
Arnaldo Carvalho de Melo
maintainerPATCH 1/23 perf test: Silence tracepoint event failures
From: Namhyung Kim <[email protected]>
Currently, when 'perf test' is run by a normal user, it'll fail to access tracepoint events. The output becomes somewhat messy because it tries to be nice with long error messages and hints.
IMHO this is not needed for 'perf test' by default and AFAIK 'perf test' uses pr_debug() rather than pr_err() for such messages so that one can use -v option to see further details on failed testcases if needed.
Before:
$ perf test 1: vmlinux symtab matches kallsyms : FAILED! 2: detect openat syscall event :Error: No permissions to read /sys/kernel/debug/tracing/events/syscalls/sys_enter_openat Hint: Try 'sudo mount -o remount,mode=755 /sys/kernel/debug/tracing' FAILED! 3: detect openat syscall event on all cpus :Error: No permissions to read /sys/kernel/debug/tracing/events/syscalls/sys_enter_openat Hint: Try 'sudo mount -o remount,mode=755 /sys/kernel/debug/tracing' FAILED! ...
After:
$ perf test 1: vmlinux symtab matches kallsyms : FAILED! 2: detect openat syscall event : FAILED! 3: detect openat syscall event on all cpus : FAILED! ...
$ perf test -v 2 2: detect openat syscall event : --- start --- test child forked, pid 30575 Error: No permissions to read /sys/kernel/debug/tracing/events/syscalls/sys_enter_openat Hint: Try 'sudo mount -o remount,mode=755 /sys/kernel/debug/tracing'
test child finished with -1
---- end ----
detect openat syscall event: FAILED!
--- tools/perf/tests/openat-syscall-all-cpus.c | 2 +- tools/perf/tests/openat-syscall-tp-fields.c | 2 +- tools/perf/tests/openat-syscall.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-)
tools/perf/tests/openat-syscall-all-cpus.c +1 -1
@@ -34,7 +34,7 @@ int test__openat_syscall_event_on_all_cpus(void) evsel =perf_evsel__newtp ("syscalls" ,"sys_enter_openat" );if (IS_ERR (evsel)) {tracing_path__strerror_open_tp (errno, errbuf,sizeof (errbuf),"syscalls" ,"sys_enter_openat" ); -pr_err ("%s\n" , errbuf); +pr_debug ("%s\n" , errbuf); goto out_thread_map_delete; }
tools/perf/tests/openat-syscall-tp-fields.c +1 -1
@@ -89,7 +89,7 @@ int test__syscall_openat_tp_fields(void) err =perf_evsel__parse_sample (evsel, event, &sample);if (err) { -pr_err ("Can't parse sample, err = %d\n" , err); +pr_debug ("Can't parse sample, err = %d\n" , err); goto out_delete_evlist; }
tools/perf/tests/openat-syscall.c +1 -1
@@ -22,7 +22,7 @@ int test__openat_syscall_event(void) evsel =perf_evsel__newtp ("syscalls" ,"sys_enter_openat" );if (IS_ERR (evsel)) {tracing_path__strerror_open_tp (errno, errbuf,sizeof (errbuf),"syscalls" ,"sys_enter_openat" ); -pr_err ("%s\n" , errbuf); +pr_debug ("%s\n" , errbuf); goto out_thread_map_delete; }
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 2/23 perf test: Suppress libtraceevent warnings
In reply to Arnaldo Carvalho de MeloFrom: Namhyung Kim <[email protected]>
Currently libtraceevent emits warning on unsupported event formats. However it'd be better to see them only -v option is given. To do that, it needs to override the warning() function which is used in the libtracevent. Thus add set_warning_routine() same as set_die_routine() and check the verbose flag in our warning routine.
Before:
# perf test 5
5: parse events tests :
Warning: [kvmmmu:kvm_mmu_get_page] bad op token {
Warning: [kvmmmu:kvm_mmu_sync_page] bad op token {
Warning: [kvmmmu:kvm_mmu_unsync_page] bad op token {
Warning: [kvmmmu:kvm_mmu_prepare_zap_page] bad op token {
Warning: [kvmmmu:fast_page_fault] function is_writable_pte not defined
...
OkAfter:
# perf test 5 5: parse events tests : Ok
--- tools/perf/tests/parse-events.c | 14 ++++++++++++++ tools/perf/util/usage.c | 5 +++++ tools/perf/util/util.h | 1 + 3 files changed, 20 insertions(+)
tools/perf/tests/parse-events.c +14 -0
@@ -5,6 +5,7 @@#include <api/fs/fs.h> #include "tests.h" #include "debug.h" +#include "util.h" #include <linux/hw_breakpoint.h> #include <api/fs/fs.h>
@@ -1753,6 +1754,17 @@ static int test_pmu_events(void)return ret; } +static void debug_warn (const char *warn,va_list params) +{ +char msg[1024 ]; + +if (!verbose) +return ; + +vsnprintf (msg,sizeof (msg), warn, params); +fprintf (stderr," Warning: %s\n" , msg); +} +int test__parse_events (void ) {int ret1, ret2 =0 ;
@@ -1764,6 +1776,8 @@ do { \ ret2 = ret1; \ }while (0 ) +set_warning_routine (debug_warn); +TEST_EVENTS (test__events);if (test_pmu ())
tools/perf/util/usage.c +5 -0
@@ -50,6 +50,11 @@ void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN) die_routine = routine; } +void set_warning_routine (void (*routine)(const char *err,va_list params)) +{ + warn_routine = routine; +} +void usage (const char *err) {usage_routine (err);
tools/perf/util/util.h +1 -0
@@ -145,6 +145,7 @@ extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2)))extern void set_die_routine (void (*routine)(const char *err,va_list params)NORETURN ); +extern void set_warning_routine (void (*routine)(const char *err,va_list params));extern int prefixcmp (const char *str,const char *prefix);extern void set_buildid_dir (const char *dir);
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 3/23 perf bench: Improve the 'perf bench mem memcpy' code readability
In reply to Arnaldo Carvalho de MeloFrom: Ingo Molnar <[email protected]>
- 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.0
Arnaldo Carvalho de Melo
maintainerPATCH 4/23 perf bench: Default to all routines in 'perf bench mem'
In reply to Arnaldo Carvalho de MeloFrom: Ingo Molnar <[email protected]>
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"),
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 5/23 perf bench: Eliminate unused argument from bench_mem_common()
In reply to Arnaldo Carvalho de MeloFrom: Ingo Molnar <[email protected]>
--- 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.0
Arnaldo Carvalho de Melo
maintainerPATCH 6/23 perf bench: Rename 'mem-memcpy.c' => 'mem-functions.c'
In reply to Arnaldo Carvalho de MeloFrom: Ingo Molnar <[email protected]>
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(-)
rename tools/perf/bench/{mem-memcpy.c => mem-functions.c} (100%)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
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 7/23 perf bench: Remove the prefaulting complication from 'perf bench mem mem*'
In reply to Arnaldo Carvalho de MeloFrom: Ingo Molnar <[email protected]>
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
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 8/23 perf bench: List output formatting options on 'perf bench -h'
In reply to Arnaldo Carvalho de MeloFrom: Ingo Molnar <[email protected]>
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 () };
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 9/23 perf bench mem: Change 'cycle' to 'cycles'
In reply to Arnaldo Carvalho de MeloFrom: Ingo Molnar <[email protected]>
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
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 10/23 perf bench mem: Rename 'routine' to 'routine_str'
In reply to Arnaldo Carvalho de MeloFrom: Ingo Molnar <[email protected]>
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",
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 11/23 perf bench mem: Fix 'length' vs. 'size' naming confusion
In reply to Arnaldo Carvalho de MeloFrom: Ingo Molnar <[email protected]>
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
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 12/23 perf bench mem: Improve user visible strings
In reply to Arnaldo Carvalho de MeloFrom: Ingo Molnar <[email protected]>
- 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.0
Arnaldo Carvalho de Melo
maintainerPATCH 13/23 perf bench mem: Reorganize the code a bit
In reply to Arnaldo Carvalho de MeloFrom: Ingo Molnar <[email protected]>
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 = {
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 14/23 perf bench: Harmonize all the -l/--nr_loops options
In reply to Arnaldo Carvalho de MeloFrom: Ingo Molnar <[email protected]>
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() };
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 15/23 perf bench mem: Rename 'routine' to 'function'
In reply to Arnaldo Carvalho de MeloFrom: Ingo Molnar <[email protected]>
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
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 16/23 perf bench: Run benchmarks, don't test them
In reply to Arnaldo Carvalho de MeloFrom: Ingo Molnar <[email protected]>
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 } };
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 17/23 perf help: Change 'usage' to 'Usage' for consistency
In reply to Arnaldo Carvalho de MeloFrom: Yunlong Song <[email protected]>
Capitalize 'usage' to make it consistent with all the other 'Usage' in the codes, e.g., usage_builtin.
--- tools/perf/builtin-help.c | 2 +- tools/perf/util/parse-options.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
tools/perf/builtin-help.c +1 -1
@@ -463,7 +463,7 @@ int cmd_help(int argc, const char **argv, const char *prefix __maybe_unused) builtin_help_subcommands, builtin_help_usage, 0);if (show_all) { -printf ("\n usage: %s\n\n" , perf_usage_string); +printf ("\n Usage: %s\n\n" , perf_usage_string);list_commands ("perf commands" , &main_cmds, &other_cmds);printf (" %s\n\n" , perf_more_info_string);return 0 ;
tools/perf/util/parse-options.c +2 -2
@@ -648,7 +648,7 @@ int usage_with_options_internal(const char * const *usagestr,if (!usagestr)return PARSE_OPT_HELP ; -fprintf (stderr,"\n usage: %s\n" , *usagestr++); +fprintf (stderr,"\n Usage: %s\n" , *usagestr++);while (*usagestr && **usagestr)fprintf (stderr," or: %s\n" , *usagestr++);while (*usagestr) {
@@ -684,7 +684,7 @@ int parse_options_usage(const char * const *usagestr,if (!usagestr) goto opt; -fprintf (stderr,"\n usage: %s\n" , *usagestr++); +fprintf (stderr,"\n Usage: %s\n" , *usagestr++);while (*usagestr && **usagestr)fprintf (stderr," or: %s\n" , *usagestr++);while (*usagestr) {
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 18/23 perf stat: Rename perf_stat struct into perf_stat_evsel
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
It's used as the perf_evsel::priv data, so the name suits better. Also we'll need the perf_stat name free for more generic struct.
--- tools/perf/builtin-stat.c | 4 ++-- tools/perf/util/stat.c | 10 +++++----- tools/perf/util/stat.h | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-)
tools/perf/builtin-stat.c +2 -2
@@ -434,7 +434,7 @@ static void print_noise_pct(double total, double avg)static void print_noise (struct perf_evsel *evsel,double avg) { -struct perf_stat *ps; +struct perf_stat_evsel *ps;if (run_count ==1 )return ;
@@ -671,7 +671,7 @@ static void print_aggr_thread(struct perf_evsel *counter, char *prefix)static void print_counter_aggr (struct perf_evsel *counter,char *prefix) {FILE *output = stat_config.output; -struct perf_stat *ps = counter->priv; +struct perf_stat_evsel *ps = counter->priv;double avg =avg_stats (&ps->res_stats[0 ]);int scaled = counter->counts->scaled;double uval;
tools/perf/util/stat.c +5 -5
@@ -67,7 +67,7 @@ double rel_stddev_stats(double stddev, double avg)bool __perf_evsel_stat__is (struct perf_evsel *evsel,enum perf_stat_evsel_id id) { -struct perf_stat *ps = evsel->priv; +struct perf_stat_evsel *ps = evsel->priv;return ps->id == id; }
@@ -84,7 +84,7 @@ static const char *id_str[PERF_STAT_EVSEL_ID__MAX] = {void perf_stat_evsel_id_init (struct perf_evsel *evsel) { -struct perf_stat *ps = evsel->priv; +struct perf_stat_evsel *ps = evsel->priv;int i;/* ps->id is 0 hence PERF_STAT_EVSEL_ID__NONE by default */
@@ -100,7 +100,7 @@ void perf_stat_evsel_id_init(struct perf_evsel *evsel)void perf_evsel__reset_stat_priv (struct perf_evsel *evsel) {int i; -struct perf_stat *ps = evsel->priv; +struct perf_stat_evsel *ps = evsel->priv;for (i =0 ; i <3 ; i++)init_stats (&ps->res_stats[i]);
@@ -110,7 +110,7 @@ void perf_evsel__reset_stat_priv(struct perf_evsel *evsel)int perf_evsel__alloc_stat_priv (struct perf_evsel *evsel) { - evsel->priv =zalloc (sizeof (struct perf_stat )); + evsel->priv =zalloc (sizeof (struct perf_stat_evsel ));if (evsel->priv ==NULL )return -ENOMEM ;perf_evsel__reset_stat_priv (evsel);
@@ -304,7 +304,7 @@ int perf_stat_process_counter(struct perf_stat_config *config, struct perf_evsel *counter) {struct perf_counts_values *aggr = &counter->counts->aggr; -struct perf_stat *ps = counter->priv; +struct perf_stat_evsel *ps = counter->priv;u64 *count = counter->counts->aggr.values;int i, ret;
tools/perf/util/stat.h +1 -1
@@ -20,7 +20,7 @@ enum perf_stat_evsel_id { PERF_STAT_EVSEL_ID__MAX, }; -struct perf_stat { +struct perf_stat_evsel {struct stats res_stats[3 ];enum perf_stat_evsel_id id; };
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 19/23 perf stat: Add AGGR_UNSET mode
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Adding AGGR_UNSET mode, so we could distinguish unset aggr_mode in following patches.
--- tools/perf/builtin-stat.c | 5 +++++ tools/perf/util/stat.c | 1 + tools/perf/util/stat.h | 1 + 3 files changed, 7 insertions(+)
tools/perf/builtin-stat.c +5 -0
@@ -479,6 +479,7 @@ static void aggr_printout(struct perf_evsel *evsel, int id, int nr) csv_sep);break ;case AGGR_GLOBAL : +case AGGR_UNSET :default :break ; }
@@ -799,6 +800,8 @@ static void print_interval(char *prefix, struct timespec *ts)case AGGR_GLOBAL :default :fprintf (output,"# time counts %*s events\n" , unit_width,"unit" ); +case AGGR_UNSET : +break ; } }
@@ -880,6 +883,7 @@ static void print_counters(struct timespec *ts, int argc, const char **argv)evlist__for_each (evsel_list, counter)print_counter (counter, prefix);break ; +case AGGR_UNSET :default :break ; }
@@ -960,6 +964,7 @@ static int perf_stat_init_aggr_mode(void)case AGGR_NONE :case AGGR_GLOBAL :case AGGR_THREAD : +case AGGR_UNSET :default :break ; }
tools/perf/util/stat.c +1 -0
@@ -272,6 +272,7 @@ process_counter_values(struct perf_stat_config *config, struct perf_evsel *evsel aggr->ena += count->ena; aggr->run += count->run; } +case AGGR_UNSET :default :break ; }
tools/perf/util/stat.h +1 -0
@@ -31,6 +31,7 @@ enum aggr_mode {AGGR_SOCKET ,AGGR_CORE ,AGGR_THREAD , + AGGR_UNSET, }; struct perf_stat_config {
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 20/23 perf cpu_map: Make cpu_map__build_map global
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
We'll need to call it from perf stat in the stat_script patchkit
--- tools/perf/util/cpumap.c | 4 ++-- tools/perf/util/cpumap.h | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-)
tools/perf/util/cpumap.c +2 -2
@@ -258,8 +258,8 @@ static int cmp_ids(const void *a, const void *b)return *(int *)a - *(int *)b; } -static int cpu_map__build_map (struct cpu_map *cpus,struct cpu_map **res, -int (*f)(struct cpu_map *map,int cpu)) +int cpu_map__build_map (struct cpu_map *cpus,struct cpu_map **res, +int (*f)(struct cpu_map *map,int cpu)) {struct cpu_map *c;int nr = cpus->nr;
tools/perf/util/cpumap.h +2 -0
@@ -87,4 +87,6 @@ static inline int cpu__get_node(int cpu) return cpunode_map[cpu]; } +int cpu_map__build_map (struct cpu_map *cpus,struct cpu_map **res, +int (*f)(struct cpu_map *map,int cpu));#endif /* __PERF_CPUMAP_H */
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 21/23 perf cpu_map: Add data arg to cpu_map__build_map callback
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
Adding data arg to cpu_map__build_map callback, so we could pass data along to the callback. It'll be needed in following patches to retrieve topology info from perf.data.
--- tools/perf/builtin-stat.c | 14 ++++++++++++-- tools/perf/tests/topology.c | 4 ++-- tools/perf/util/cpumap.c | 15 ++++++++------- tools/perf/util/cpumap.h | 7 ++++--- tools/perf/util/stat.c | 2 +- 5 files changed, 27 insertions(+), 15 deletions(-)
tools/perf/builtin-stat.c +12 -2
@@ -944,6 +944,16 @@ static int stat__set_big_num(const struct option *opt __maybe_unused,return 0 ; } +static int perf_stat__get_socket (struct cpu_map *map,int cpu) +{ +return cpu_map__get_socket (map, cpu,NULL ); +} + +static int perf_stat__get_core (struct cpu_map *map,int cpu) +{ +return cpu_map__get_core (map, cpu,NULL ); +} +static int perf_stat_init_aggr_mode (void ) {switch (stat_config.aggr_mode) {
@@ -952,14 +962,14 @@ static int perf_stat_init_aggr_mode(void)perror ("cannot build socket map" );return -1 ; } - aggr_get_id = cpu_map__get_socket; + aggr_get_id = perf_stat__get_socket;break ;case AGGR_CORE :if (cpu_map__build_core_map (evsel_list->cpus, &aggr_map)) {perror ("cannot build core map" );return -1 ; } - aggr_get_id = cpu_map__get_core; + aggr_get_id = perf_stat__get_core;break ;case AGGR_NONE :case AGGR_GLOBAL :
tools/perf/tests/topology.c +2 -2
@@ -73,10 +73,10 @@ static int check_cpu_topology(char *path, struct cpu_map *map)for (i =0 ; i < map->nr; i++) {TEST_ASSERT_VAL ("Core ID doesn't match" , - (session->header.env.cpu[map->map[i]].core_id == (cpu_map__get_core (map, i) &0xffff ))); + (session->header.env.cpu[map->map[i]].core_id == (cpu_map__get_core (map, i,NULL ) &0xffff )));TEST_ASSERT_VAL ("Socket ID doesn't match" , - (session->header.env.cpu[map->map[i]].socket_id ==cpu_map__get_socket (map, i))); + (session->header.env.cpu[map->map[i]].socket_id ==cpu_map__get_socket (map, i,NULL ))); }perf_session__delete (session);
tools/perf/util/cpumap.c +8 -7
@@ -241,7 +241,7 @@ int cpu_map__get_socket_id(int cpu)return ret ?: value; } -int cpu_map__get_socket (struct cpu_map *map,int idx) +int cpu_map__get_socket (struct cpu_map *map,int idx,void *data__maybe_unused ) {int cpu;
@@ -259,7 +259,8 @@ static int cmp_ids(const void *a, const void *b) }int cpu_map__build_map (struct cpu_map *cpus,struct cpu_map **res, -int (*f)(struct cpu_map *map,int cpu)) +int (*f)(struct cpu_map *map,int cpu,void *data), +void *data) {struct cpu_map *c;int nr = cpus->nr;
@@ -271,7 +272,7 @@ int cpu_map__build_map(struct cpu_map *cpus, struct cpu_map **res,return -1 ;for (cpu =0 ; cpu < nr; cpu++) { - s1 =f (cpus, cpu); + s1 =f (cpus, cpu, data);for (s2 =0 ; s2 < c->nr; s2++) {if (s1 == c->map[s2])break ;
@@ -295,7 +296,7 @@ int cpu_map__get_core_id(int cpu)return ret ?: value; } -int cpu_map__get_core (struct cpu_map *map,int idx) +int cpu_map__get_core (struct cpu_map *map,int idx,void *data) {int cpu, s;
@@ -306,7 +307,7 @@ int cpu_map__get_core(struct cpu_map *map, int idx) cpu =cpu_map__get_core_id (cpu); - s =cpu_map__get_socket (map, idx); + s =cpu_map__get_socket (map, idx, data);if (s ==-1 )return -1 ;
@@ -321,12 +322,12 @@ int cpu_map__get_core(struct cpu_map *map, int idx)int cpu_map__build_socket_map (struct cpu_map *cpus,struct cpu_map **sockp) { -return cpu_map__build_map (cpus, sockp, cpu_map__get_socket); +return cpu_map__build_map (cpus, sockp, cpu_map__get_socket,NULL ); }int cpu_map__build_core_map (struct cpu_map *cpus,struct cpu_map **corep) { -return cpu_map__build_map (cpus, corep, cpu_map__get_core); +return cpu_map__build_map (cpus, corep, cpu_map__get_core,NULL ); }/* setup simple routines to easily access node numbers given a cpu number */
tools/perf/util/cpumap.h +4 -3
@@ -19,9 +19,9 @@ struct cpu_map *cpu_map__dummy_new(void);struct cpu_map *cpu_map__read (FILE *file);size_t cpu_map__fprintf (struct cpu_map *map,FILE *fp);int cpu_map__get_socket_id (int cpu); -int cpu_map__get_socket (struct cpu_map *map,int idx); +int cpu_map__get_socket (struct cpu_map *map,int idx,void *data);int cpu_map__get_core_id (int cpu); -int cpu_map__get_core (struct cpu_map *map,int idx); +int cpu_map__get_core (struct cpu_map *map,int idx,void *data);int cpu_map__build_socket_map (struct cpu_map *cpus,struct cpu_map **sockp);int cpu_map__build_core_map (struct cpu_map *cpus,struct cpu_map **corep);
@@ -88,5 +88,6 @@ static inline int cpu__get_node(int cpu) }int cpu_map__build_map (struct cpu_map *cpus,struct cpu_map **res, -int (*f)(struct cpu_map *map,int cpu)); +int (*f)(struct cpu_map *map,int cpu,void *data), +void *data);#endif /* __PERF_CPUMAP_H */
tools/perf/util/stat.c +1 -1
@@ -230,7 +230,7 @@ static int check_per_pkg(struct perf_evsel *counter,if (!(vals->run && vals->ena))return 0 ; - s =cpu_map__get_socket (cpus, cpu); + s =cpu_map__get_socket (cpus, cpu,NULL );if (s <0 )return -1 ;
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 22/23 perf script: Check output fields only for samples
In reply to Arnaldo Carvalho de MeloFrom: Jiri Olsa <[email protected]>
There's no need to check sampling output fields for events without perf_event_attr::sample_type field set.
--- tools/perf/builtin-script.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
tools/perf/builtin-script.c +4 -1
@@ -686,7 +686,10 @@ static int process_attr(struct perf_tool *tool, union perf_event *event,set_print_ip_opts (&evsel->attr); -return perf_evsel__check_attr (evsel, scr->session); +if (evsel->attr.sample_type) + err =perf_evsel__check_attr (evsel, scr->session); + +return err; } static int process_comm_event(struct perf_tool *tool,
Signature · 1 line
2.1.0
Arnaldo Carvalho de Melo
maintainerPATCH 23/23 perf bench: Use named initializers in the trailer too
In reply to Arnaldo Carvalho de MeloFrom: Arnaldo Carvalho de Melo <[email protected]>
To avoid this splat with gcc 4.4.7:
cc1: warnings being treated as errors
bench/mem-functions.c:273: error: missing initializer bench/mem-functions.c:273: error: (near initialization for ‘memcpy_functions[4].desc’) bench/mem-functions.c:366: error: missing initializer bench/mem-functions.c:366: error: (near initialization for ‘memset_functions[4].desc’)
--- tools/perf/bench/mem-functions.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/perf/bench/mem-functions.c +2 -2
@@ -270,7 +270,7 @@ struct function memcpy_functions[] = {# undef MEMCPY_FN#endif - { NULL, } + { .name = NULL, } };static const char *const bench_mem_memcpy_usage[] = {
@@ -363,7 +363,7 @@ static const struct function memset_functions[] = {# undef MEMSET_FN#endif - { NULL, } + { .name = NULL, } };int bench_mem_memset (int argc,const char **argv,const char *prefix__maybe_unused )
Signature · 1 line
2.1.0
Quoted 99 lines · Arnaldo Carvalho de Melo
Hi Ingo,
Please consider pulling,
- Arnaldo
The following changes since commit
e9363deeb286e916353f11b11d1f351c6ff54082:Merge tag 'perf-core-for-mingo' of
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linuxinto perf/core (2015-10-14 15:06:33 +0200)are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.gittags/perf-core-for-mingofor you to fetch changes up to
a4c6a3e8bbb675a601f529881c51ff226f83c3f1:perf bench: Use named initializers in the trailer too (2015-10-19 18:17:25 -0300)
----------------------------------------------------------------
perf/core improvements and fixes:User visible:
- 'perf bench mem' now prefaults unconditionally, no sense in providing modes where page faults are measured (Ingo Molnar)
- Harmonize -l/--nr_loops accross 'perf bench' (Ingo Molnar)
- Various 'perf bench' consistency improvements (Ingo Molnar)
- Suppress libtraceevent warnings in non-verbose 'perf test' mode (Namhyung Kim)
- Move some tracepoint event test error messages to the verbose mode of 'perf test' (Namhyung Kim)
- Make 'perf help' usage message consistent with other tools (Yunlong Song)
Build fixes:
- Fix 'perf bench' build with gcc 4.4.7 (Arnaldo Carvalho de Melo)
Infrastructure:
- 'perf stat' prep work for the 'perf stat scripting' patchkit (Jiri Olsa)
Signed-off-by Arnaldo Carvalho de Melo <[email protected]>----------------------------------------------------------------
Arnaldo Carvalho de Melo (1):
perf bench: Use named initializers in the trailer tooIngo 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 frombench_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 themJiri Olsa (5):
perf stat: Renameperf_statstruct intoperf_stat_evselperf stat: AddAGGR_UNSETmode
perfcpu_map: Makecpu_map__build_mapglobal perfcpu_map: Add data arg tocpu_map__build_mapcallback perf script: Check output fields only for samplesNamhyung Kim (2):
perf test: Silence tracepoint event failures perf test: Suppress libtraceevent warningsYunlong Song (1):
perf help: Change 'usage' to 'Usage' for consistencytools/perf/Documentation/perf-bench.txt | 54 ++-- 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 +- tools/perf/builtin-help.c | 2 +- tools/perf/builtin-script.c | 5 +- tools/perf/builtin-stat.c | 23 +- tools/perf/tests/openat-syscall-all-cpus.c | 2 +- tools/perf/tests/openat-syscall-tp-fields.c | 2 +- tools/perf/tests/openat-syscall.c | 2 +- tools/perf/tests/parse-events.c | 14 + tools/perf/tests/topology.c | 4 +- tools/perf/util/cpumap.c | 17 +- tools/perf/util/cpumap.h | 7 +-
Quoted 8 lines
tools/perf/util/parse-options.c | 4 +- tools/perf/util/stat.c | 13 +- tools/perf/util/stat.h | 3 +- tools/perf/util/usage.c | 5 + tools/perf/util/util.h | 1 + 22 files changed, 487 insertions(+), 514 deletions(-) create mode 100644 tools/perf/bench/mem-functions.c delete mode 100644 tools/perf/bench/mem-memcpy.c
Pulled, thanks a lot Arnaldo!
Ingo