Misc perf stat improvements
Here are a couple of perf stat improvements/cleanups:
- output more information (ratios) in CSV mode
- add --initial-delay to skip startup phase of program
- handle pipes better in interval mode
- some cleanup
PATCH 1/5 perf, tools: Remove obsolete dummy execve
From: Andi Kleen <[email protected]>
Minor cleanup.
The dummy execve to pre-resolve the PLT is obsolete since "enable_on_execve" was added. The counters are only running after the execve anyways. So just remove it.
--- tools/perf/util/evlist.c | 7 ------- 1 file changed, 7 deletions(-)
tools/perf/util/evlist.c +0 -7
@@ -783,13 +783,6 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist,fcntl (go_pipe[0 ],F_SETFD ,FD_CLOEXEC );/* -* Do a dummy execvp to get the PLT entry resolved, -* so we avoid the resolver overhead on the real -* execvp call. -*/ -execvp ("" , (char **)argv); - -/* * Tell the parent we're ready to go */ close (child_ready_pipe[1 ]);
Signature · 1 line
1.8.3.1
tip-bot for Andi Kleen
merge bot[tip:perf/core] perf evlist: Remove obsolete dummy execve
perf evlist: Remove obsolete dummy execve
Commit-ID: 5c6974f49832a55edc9ca744323778947c104ca0 Gitweb: http://git.kernel.org/tip/5c6974f49832a55edc9ca744323778947c104ca0 Author: Andi Kleen <[email protected]> AuthorDate: Fri, 2 Aug 2013 17:41:09 -0700 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Wed, 7 Aug 2013 17:35:28 -0300
perf evlist: Remove obsolete dummy execve
Minor cleanup.
The dummy execve to pre-resolve the PLT is obsolete since "enable_on_execve" was added. The counters are only running after the execve anyways. So just remove it.
--- tools/perf/util/evlist.c | 7 ------- 1 file changed, 7 deletions(-)
tools/perf/util/evlist.c +0 -7
@@ -837,13 +837,6 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist,fcntl (go_pipe[0 ],F_SETFD ,FD_CLOEXEC );/* -* Do a dummy execvp to get the PLT entry resolved, -* so we avoid the resolver overhead on the real -* execvp call. -*/ -execvp ("" , (char **)argv); - -/* * Tell the parent we're ready to go */ close (child_ready_pipe[1 ]);
PATCH 2/5 tools, perf: Add support to evsel for enabling counters
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
Add support for enabling already set up counters by using an ioctl. I share some code with the filter setup.
--- tools/perf/util/evsel.c | 21 ++++++++++++++++++--- tools/perf/util/evsel.h | 1 + 2 files changed, 19 insertions(+), 3 deletions(-)
tools/perf/util/evsel.c +18 -3
@@ -605,16 +605,16 @@ int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)return evsel->fd !=NULL ?0 : -ENOMEM ; } -int perf_evsel__set_filter (struct perf_evsel *evsel,int ncpus,int nthreads, -const char *filter) +static int perf_evsel__run_ioctl (struct perf_evsel *evsel,int ncpus,int nthreads, +int ioc,void *arg) {int cpu, thread;for (cpu =0 ; cpu < ncpus; cpu++) {for (thread =0 ; thread < nthreads; thread++) {int fd =FD (evsel, cpu, thread), - err =ioctl (fd,PERF_EVENT_IOC_SET_FILTER , filter); + err =ioctl (fd, ioc, arg);if (err)return err; }
@@ -623,6 +623,21 @@ int perf_evsel__set_filter(struct perf_evsel *evsel, int ncpus, int nthreads,return 0 ; } +int perf_evsel__set_filter (struct perf_evsel *evsel,int ncpus,int nthreads, +const char *filter) +{ +return perf_evsel__run_ioctl (evsel, ncpus, nthreads, +PERF_EVENT_IOC_SET_FILTER , + (void *)filter); +} + +int perf_evsel__enable (struct perf_evsel *evsel,int ncpus,int nthreads) +{ +return perf_evsel__run_ioctl (evsel, ncpus, nthreads, +PERF_EVENT_IOC_ENABLE , +0 ); +} +int perf_evsel__alloc_id (struct perf_evsel *evsel,int ncpus,int nthreads) { evsel->sample_id =xyarray__new (ncpus, nthreads,sizeof (struct perf_sample_id ));
tools/perf/util/evsel.h +1 -0
@@ -142,6 +142,7 @@ void perf_evsel__set_sample_id(struct perf_evsel *evsel);int perf_evsel__set_filter (struct perf_evsel *evsel,int ncpus,int nthreads,const char *filter); +int perf_evsel__enable (struct perf_evsel *evsel,int ncpus,int nthreads);int perf_evsel__open_per_cpu (struct perf_evsel *evsel,struct cpu_map *cpus);
Signature · 1 line
1.8.3.1
Namhyung Kim
maintainerRe: [PATCH 2/5] tools, perf: Add support to evsel for enabling counters
Hi Andi,
Quoted 22 lines · Andi Kleen
From: Andi Kleen <[email protected]>
Add support for enabling already set up counters by using an ioctl. I share some code with the filter setup.
Signed-off-by Andi Kleen <[email protected]>--- tools/perf/util/evsel.c | 21 ++++++++++++++++++--- tools/perf/util/evsel.h | 1 + 2 files changed, 19 insertions(+), 3 deletions(-)tools/perf/util/evsel.c +1
-2@@ -605,16 +605,16 @@ int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)return evsel->fd !=NULL ?0 : -ENOMEM ; } -int perf_evsel__set_filter (struct perf_evsel *evsel,int ncpus,int nthreads, -const char *filter) +static int perf_evsel__run_ioctl(struct perf_evsel *evsel, int ncpus, int nthreads,
tools/perf/util/evsel.c int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) · line 617
Quoted 10 lines
tools/perf/util/evsel.c +2
-1+ int ioc, void *arg) { int cpu, thread;for (cpu =0 ; cpu < ncpus; cpu++) {for (thread =0 ; thread < nthreads; thread++) {int fd =FD (evsel, cpu, thread), - err =ioctl (fd,PERF_EVENT_IOC_SET_FILTER , filter); + err =ioctl (fd, ioc, arg);
Looks very strange to have a blank line between variable declarations. You'd better separating declarations on the other lines like:
int fd, err; fd = FD(evsel, cpu, thread); err = ioctl(fd, ioc, arg);
Thanks,
Namhyung
Quoted 3 lines
tools/perf/util/evsel.c +0
-0if (err)return err; }
Re: [PATCH 2/5] tools, perf: Add support to evsel for enabling counters
Em Mon, Aug 05, 2013 at 05:28:14PM +0900, Namhyung Kim escreveu:
Quoted 39 lines
Hi Andi,
Quoted 22 lines · Andi Kleen
From: Andi Kleen <[email protected]>
Add support for enabling already set up counters by using an ioctl. I share some code with the filter setup.
Signed-off-by Andi Kleen <[email protected]>--- tools/perf/util/evsel.c | 21 ++++++++++++++++++--- tools/perf/util/evsel.h | 1 + 2 files changed, 19 insertions(+), 3 deletions(-)tools/perf/util/evsel.c +1
-2@@ -605,16 +605,16 @@ int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)return evsel->fd !=NULL ?0 : -ENOMEM ; } -int perf_evsel__set_filter (struct perf_evsel *evsel,int ncpus,int nthreads, -const char *filter) +static int perf_evsel__run_ioctl(struct perf_evsel *evsel, int ncpus, int nthreads,tools/perf/util/evsel.c int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads) · line 617
Quoted 10 lines
tools/perf/util/evsel.c +2
-1+ int ioc, void *arg) { int cpu, thread;for (cpu =0 ; cpu < ncpus; cpu++) {for (thread =0 ; thread < nthreads; thread++) {int fd =FD (evsel, cpu, thread), - err =ioctl (fd,PERF_EVENT_IOC_SET_FILTER , filter); + err =ioctl (fd, ioc, arg);Looks very strange to have a blank line between variable declarations. You'd better separating declarations on the other lines like:
Quoted 4 lines
int fd, err; fd = FD(evsel, cpu, thread); err = ioctl(fd, ioc, arg);
Preferences :-) I think the best way is:
int fd = FD(evsel, cpu, thread), err = ioctl(fd, ioc, arg);
As its all short and so uses 2 instead of 4 lines. I'll fix up the alignment.
Quoted 8 lines
Thanks,
NamhyungQuoted 3 lines
tools/perf/util/evsel.c +0
-0if (err)return err; }
tip-bot for Andi Kleen
merge bot[tip:perf/core] perf evsel: Add support for enabling counters
In reply to Andi Kleenperf evsel: Add support for enabling counters
Commit-ID: e2407bef968d64a28465561832686636d3380bf9 Gitweb: http://git.kernel.org/tip/e2407bef968d64a28465561832686636d3380bf9 Author: Andi Kleen <[email protected]> AuthorDate: Fri, 2 Aug 2013 17:41:10 -0700 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Wed, 7 Aug 2013 17:35:28 -0300
perf evsel: Add support for enabling counters
Add support for enabling already set up counters by using an ioctl. I share some code with the filter setup.
--- tools/perf/util/evsel.c | 21 ++++++++++++++++++--- tools/perf/util/evsel.h | 1 + 2 files changed, 19 insertions(+), 3 deletions(-)
tools/perf/util/evsel.c +18 -3
@@ -634,15 +634,15 @@ int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)return evsel->fd !=NULL ?0 : -ENOMEM ; } -int perf_evsel__set_filter (struct perf_evsel *evsel,int ncpus,int nthreads, -const char *filter) +static int perf_evsel__run_ioctl (struct perf_evsel *evsel,int ncpus,int nthreads, +int ioc,void *arg) {int cpu, thread;for (cpu =0 ; cpu < ncpus; cpu++) {for (thread =0 ; thread < nthreads; thread++) {int fd =FD (evsel, cpu, thread), - err =ioctl (fd,PERF_EVENT_IOC_SET_FILTER , filter); + err =ioctl (fd, ioc, arg);if (err)return err;
@@ -652,6 +652,21 @@ int perf_evsel__set_filter(struct perf_evsel *evsel, int ncpus, int nthreads,return 0 ; } +int perf_evsel__set_filter (struct perf_evsel *evsel,int ncpus,int nthreads, +const char *filter) +{ +return perf_evsel__run_ioctl (evsel, ncpus, nthreads, +PERF_EVENT_IOC_SET_FILTER , + (void *)filter); +} + +int perf_evsel__enable (struct perf_evsel *evsel,int ncpus,int nthreads) +{ +return perf_evsel__run_ioctl (evsel, ncpus, nthreads, +PERF_EVENT_IOC_ENABLE , +0 ); +} +int perf_evsel__alloc_id (struct perf_evsel *evsel,int ncpus,int nthreads) { evsel->sample_id =xyarray__new (ncpus, nthreads,sizeof (struct perf_sample_id ));
tools/perf/util/evsel.h +1 -0
@@ -146,6 +146,7 @@ void perf_evsel__set_sample_id(struct perf_evsel *evsel);int perf_evsel__set_filter (struct perf_evsel *evsel,int ncpus,int nthreads,const char *filter); +int perf_evsel__enable (struct perf_evsel *evsel,int ncpus,int nthreads);int perf_evsel__open_per_cpu (struct perf_evsel *evsel,struct cpu_map *cpus);
PATCH 3/5 perf, tools: Add support for --initial-delay option to perf stat
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
When measuring workloads the startup phase -- doing page faults, dynamic linking, opening files -- is often very different from the rest of the workload. Especially with smaller kernels and using counter multiplexing this can give significant measurement errors.
Multiplexing assumes that the workload is mostly the same over longer periods. But at startup there is typically some spike of activity which is relatively short.
If many groups are multiplexing the one group seeing the spike, and which is then scaled up over the time to run all groups, may see a significant error.
Also in general it's often not useful to measure the startup, because it is so different from the rest.
One way around this is to use interval mode and discard the first sample, but this can be awkward because interval mode doesn't support intervals of less than 100ms, and also a useful interval is not necessarily the same as a useful startup delay.
This patch adds a new --initial-delay / -D option to skip measuring for the startup phase. The time can be specified in ms
Here's a simple example:
perf stat -e page-faults bash -c 'for i in $(seq 100000) ; do true ; done'
...
3,721 page-faults
...
If we just wait 20 ms the number of page faults is 1/3 less:
perf stat -D 20 -e page-faults bash -c 'for i in $(seq 100000) ; do true ; done'
...
2,823 page-faults
...
So we filtered out most of the startup noise from bash.
--- tools/perf/Documentation/perf-stat.txt | 5 +++++ tools/perf/builtin-stat.c | 22 +++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-)
tools/perf/Documentation/perf-stat.txt +5 -0
@@ -132,6 +132,11 @@ is a useful mode to detect imbalance between physical cores. To enable this mod use --per-core in addition to -a. (system-wide). The output includes the core number and the number of online logical processors on that physical processor. +-D msecs:: +--initial-delay msecs:: +After starting the program, wait msecs before measuring. This is useful to +filter out the startup phase of the program, which is often very different. + EXAMPLES --------
tools/perf/builtin-stat.c +21 -1
@@ -100,6 +100,7 @@ static const char *pre_cmd = NULL;static const char *post_cmd =NULL ;static bool sync_run = false;static unsigned int interval =0 ; +static unsigned int initial_delay =0 ;static bool forever = false;static struct timespec ref_time;static struct cpu_map *aggr_map;
@@ -254,7 +255,8 @@ static int create_perf_stat_counter(struct perf_evsel *evsel)if (!perf_target__has_task (&target) &&perf_evsel__is_group_leader (evsel)) { attr->disabled =1 ; - attr->enable_on_exec =1 ; +if (!initial_delay) + attr->enable_on_exec =1 ; }return perf_evsel__open_per_thread (evsel, evsel_list->threads);
@@ -416,6 +418,20 @@ static void print_interval(void) } } +static void handle_initial_delay (void ) +{ +struct perf_evsel *counter; + +if (initial_delay) { +const int ncpus =cpu_map__nr (evsel_list->cpus), + nthreads =thread_map__nr (evsel_list->threads); + +usleep (initial_delay *1000 ); +list_for_each_entry (counter, &evsel_list->entries, node) +perf_evsel__enable (counter, ncpus, nthreads); + } +} +static int __run_perf_stat (int argc,const char **argv) {char msg[512 ];
@@ -486,6 +502,7 @@ static int __run_perf_stat(int argc, const char **argv)if (forks) {perf_evlist__start_workload (evsel_list); +handle_initial_delay ();if (interval) {while (!waitpid (child_pid, &status,WNOHANG )) {
@@ -497,6 +514,7 @@ static int __run_perf_stat(int argc, const char **argv)if (WIFSIGNALED (status))psignal (WTERMSIG (status), argv[0 ]); }else { +handle_initial_delay ();while (!done) {nanosleep (&ts,NULL );if (interval)
@@ -1419,6 +1437,8 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused) "aggregate counts per processor socket", AGGR_SOCKET),OPT_SET_UINT (0 ,"per-core" , &aggr_mode,"aggregate counts per physical processor core" ,AGGR_CORE ), +OPT_UINTEGER ('D' ,"delay" , &initial_delay, +"ms to wait before starting measurement after program start" ),OPT_END () }; const char * const stat_usage[] = {
Signature · 1 line
1.8.3.1
tip-bot for Andi Kleen
merge bot[tip:perf/core] perf stat: Add support for --initial-delay option
perf stat: Add support for --initial-delay option
Commit-ID: 411916880ff4061ac0491a154f10af4d49a0c61a Gitweb: http://git.kernel.org/tip/411916880ff4061ac0491a154f10af4d49a0c61a Author: Andi Kleen <[email protected]> AuthorDate: Fri, 2 Aug 2013 17:41:11 -0700 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Wed, 7 Aug 2013 17:35:29 -0300
perf stat: Add support for --initial-delay option
When measuring workloads the startup phase -- doing page faults, dynamic linking, opening files -- is often very different from the rest of the workload. Especially with smaller kernels and using counter multiplexing this can give significant measurement errors.
Multiplexing assumes that the workload is mostly the same over longer periods. But at startup there is typically some spike of activity which is relatively short. If many groups are multiplexing the one group seeing the spike, and which is then scaled up over the time to run all groups, may see a significant error.
Also in general it's often not useful to measure the startup, because it is so different from the rest.
One way around this is to use interval mode and discard the first sample, but this can be awkward because interval mode doesn't support intervals of less than 100ms, and also a useful interval is not necessarily the same as a useful startup delay.
This patch adds a new --initial-delay / -D option to skip measuring for the startup phase. The time can be specified in ms
Here's a simple example:
perf stat -e page-faults bash -c 'for i in $(seq 100000) ; do true ; done'
...
3,721 page-faults
...
If we just wait 20 ms the number of page faults is 1/3 less:
perf stat -D 20 -e page-faults bash -c 'for i in $(seq 100000) ; do true ; done'
...
2,823 page-faults
...
So we filtered out most of the startup noise from bash.
--- tools/perf/Documentation/perf-stat.txt | 5 +++++ tools/perf/builtin-stat.c | 22 +++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-)
tools/perf/Documentation/perf-stat.txt +5 -0
@@ -132,6 +132,11 @@ is a useful mode to detect imbalance between physical cores. To enable this mod use --per-core in addition to -a. (system-wide). The output includes the core number and the number of online logical processors on that physical processor. +-D msecs:: +--initial-delay msecs:: +After starting the program, wait msecs before measuring. This is useful to +filter out the startup phase of the program, which is often very different. + EXAMPLES --------
tools/perf/builtin-stat.c +21 -1
@@ -100,6 +100,7 @@ static const char *pre_cmd = NULL;static const char *post_cmd =NULL ;static bool sync_run = false;static unsigned int interval =0 ; +static unsigned int initial_delay =0 ;static bool forever = false;static struct timespec ref_time;static struct cpu_map *aggr_map;
@@ -254,7 +255,8 @@ static int create_perf_stat_counter(struct perf_evsel *evsel)if (!perf_target__has_task (&target) &&perf_evsel__is_group_leader (evsel)) { attr->disabled =1 ; - attr->enable_on_exec =1 ; +if (!initial_delay) + attr->enable_on_exec =1 ; }return perf_evsel__open_per_thread (evsel, evsel_list->threads);
@@ -416,6 +418,20 @@ static void print_interval(void) } } +static void handle_initial_delay (void ) +{ +struct perf_evsel *counter; + +if (initial_delay) { +const int ncpus =cpu_map__nr (evsel_list->cpus), + nthreads =thread_map__nr (evsel_list->threads); + +usleep (initial_delay *1000 ); +list_for_each_entry (counter, &evsel_list->entries, node) +perf_evsel__enable (counter, ncpus, nthreads); + } +} +static int __run_perf_stat (int argc,const char **argv) {char msg[512 ];
@@ -486,6 +502,7 @@ static int __run_perf_stat(int argc, const char **argv)if (forks) {perf_evlist__start_workload (evsel_list); +handle_initial_delay ();if (interval) {while (!waitpid (child_pid, &status,WNOHANG )) {
@@ -497,6 +514,7 @@ static int __run_perf_stat(int argc, const char **argv)if (WIFSIGNALED (status))psignal (WTERMSIG (status), argv[0 ]); }else { +handle_initial_delay ();while (!done) {nanosleep (&ts,NULL );if (interval)
@@ -1419,6 +1437,8 @@ int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused) "aggregate counts per processor socket", AGGR_SOCKET),OPT_SET_UINT (0 ,"per-core" , &aggr_mode,"aggregate counts per physical processor core" ,AGGR_CORE ), +OPT_UINTEGER ('D' ,"delay" , &initial_delay, +"ms to wait before starting measurement after program start" ),OPT_END () }; const char * const stat_usage[] = {
PATCH 4/5 perf, tools: flush output after each line in stat interval mode
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
When interval mode is outputting to a pipe, each measurement should be flushed individually, so that the reader sees it timely.
With a terminal each line is automatically flushed by stdio, but that is disabled with non terminal output.
Simply fflush output after each time interval
--- tools/perf/builtin-stat.c | 2 ++ 1 file changed, 2 insertions(+)
tools/perf/builtin-stat.c +2 -0
@@ -416,6 +416,8 @@ static void print_interval(void)list_for_each_entry (counter, &evsel_list->entries, node)print_counter_aggr (counter, prefix); } + +fflush (output); }static void handle_initial_delay (void )
Signature · 1 line
1.8.3.1
tip-bot for Andi Kleen
merge bot[tip:perf/core] perf stat: Flush output after each line in interval mode
perf stat: Flush output after each line in interval mode
Commit-ID: 2bbf03f16a634f675c49c473b2b6528571990aea Gitweb: http://git.kernel.org/tip/2bbf03f16a634f675c49c473b2b6528571990aea Author: Andi Kleen <[email protected]> AuthorDate: Fri, 2 Aug 2013 17:41:12 -0700 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Wed, 7 Aug 2013 17:35:29 -0300
perf stat: Flush output after each line in interval mode
When interval mode is outputting to a pipe, each measurement should be flushed individually, so that the reader sees it timely.
With a terminal each line is automatically flushed by stdio, but that is disabled with non terminal output.
Simply fflush output after each time interval
--- tools/perf/builtin-stat.c | 2 ++ 1 file changed, 2 insertions(+)
tools/perf/builtin-stat.c +2 -0
@@ -416,6 +416,8 @@ static void print_interval(void)list_for_each_entry (counter, &evsel_list->entries, node)print_counter_aggr (counter, prefix); } + +fflush (output); }static void handle_initial_delay (void )
PATCH 5/5 perf, tools: Output running time and run/enabled ratio in CSV mode
In reply to Andi KleenFrom: Andi Kleen <[email protected]>
The information how much a counter ran in perf stat can be quite interesting for other tools to judge how trustworthy a measurement is.
Currently it is only output in non CSV mode.
This patches make perf stat always output the running time and the enabled/running ratio in CSV mode.
This adds two new fields at the end for each line. I assume that existing tools ignore new fields at the end, so it's on by default.
Only CSV mode is affected, no difference otherwise.
--- tools/perf/builtin-stat.c | 57 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 12 deletions(-)
tools/perf/builtin-stat.c +45 -12
@@ -982,6 +982,13 @@ static void print_aggr(char *prefix)fprintf (output,"%s%s" , csv_sep, counter->cgrp->name); +if (csv_output) +fprintf (output,"%s%" PRIu64"%s%.2f" , + csv_sep, + run, + csv_sep, +100.0 * run / ena); +fputc ('\n' , output);continue ; }
@@ -997,6 +1004,12 @@ static void print_aggr(char *prefix)if (run != ena)fprintf (output," (%.2f%%)" ,100.0 * run / ena); + }else { +fprintf (output,"%s%" PRIu64"%s%.2f" , + csv_sep, + run, + csv_sep, +100.0 * run / ena); }fputc ('\n' , output); }
@@ -1012,6 +1025,10 @@ static void print_counter_aggr(struct perf_evsel *counter, char *prefix)struct perf_stat *ps = counter->priv;double avg =avg_stats (&ps->res_stats[0 ]);int scaled = counter->counts->scaled; +double avg_enabled, avg_running; + + avg_enabled =avg_stats (&ps->res_stats[1 ]); + avg_running =avg_stats (&ps->res_stats[2 ]);if (prefix)fprintf (output,"%s" , prefix);
@@ -1027,6 +1044,13 @@ static void print_counter_aggr(struct perf_evsel *counter, char *prefix)if (counter->cgrp)fprintf (output,"%s%s" , csv_sep, counter->cgrp->name); +if (csv_output) +fprintf (output,"%s%.0f%s%.2f" , + csv_sep, + avg_running, + csv_sep, +100.0 * avg_running / avg_enabled); +fputc ('\n' , output);return ; }
@@ -1038,19 +1062,14 @@ static void print_counter_aggr(struct perf_evsel *counter, char *prefix)print_noise (counter, avg); -if (csv_output) { -fputc ('\n' , output); -return ; - } - -if (scaled) { -double avg_enabled, avg_running; - - avg_enabled =avg_stats (&ps->res_stats[1 ]); - avg_running =avg_stats (&ps->res_stats[2 ]); - +if (csv_output) +fprintf (output,"%s%.0f%s%.2f" , + csv_sep, + avg_running, + csv_sep, +100.0 * avg_running / avg_enabled); +else fprintf (output," [%5.2f%%]" ,100 * avg_running / avg_enabled); - }fprintf (output,"\n" ); }
@@ -1085,6 +1104,13 @@ static void print_counter(struct perf_evsel *counter, char *prefix)fprintf (output,"%s%s" , csv_sep, counter->cgrp->name); +if (csv_output) +fprintf (output,"%s%" PRIu64"%s%.2f" , + csv_sep, + run, + csv_sep, +100.0 * run / ena); +fputc ('\n' , output);continue ; }
@@ -1100,7 +1126,14 @@ static void print_counter(struct perf_evsel *counter, char *prefix)if (run != ena)fprintf (output," (%.2f%%)" ,100.0 * run / ena); + }else { +fprintf (output,"%s%" PRIu64"%s%.2f" , + csv_sep, + run, + csv_sep, +100.0 * run / ena); } +fputc ('\n' , output); } }
Signature · 1 line
1.8.3.1
Re: [PATCH 5/5] perf, tools: Output running time and run/enabled ratio in CSV mode
Quoted 25 lines · Andi Kleen
From: Andi Kleen <[email protected]>
The information how much a counter ran in perf stat can be quite interesting for other tools to judge how trustworthy a measurement is.
Currently it is only output in non CSV mode.
This patches make perf stat always output the running time and the enabled/running ratio in CSV mode.
This adds two new fields at the end for each line. I assume that existing tools ignore new fields at the end, so it's on by default.
Only CSV mode is affected, no difference otherwise.
Signed-off-by Andi Kleen <[email protected]>--- tools/perf/builtin-stat.c | 57 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 12 deletions(-)tools/perf/builtin-stat.c +0
-0
tools/perf/builtin-stat.c static void print_aggr(char *prefix) · line 990
Quoted 9 lines
tools/perf/builtin-stat.c +6
-0@@ -982,6 +982,13 @@ static void print_aggr(char *prefix)fprintf (output,"%s%s" , csv_sep, counter->cgrp->name); +if (csv_output) +fprintf (output,"%s%" PRIu64"%s%.2f" , + csv_sep, + run, + csv_sep, +100.0 * run / ena);
looks like we could use function/macro for this
jirka
Jiri Olsa
Reviewed-byQuoted 7 lines · Andi Kleen
Here are a couple of perf stat improvements/cleanups:
- output more information (ratios) in CSV mode
- add --initial-delay to skip startup phase of program
- handle pipes better in interval mode
- some cleanup
for the patchset: