perf tools: Cache register accesses for unwind processing

Caching registers value into an array. Got about 4% speed up
of perf_reg_value function for report command processing
dwarf unwind stacks.

Output from report over 1.5 GB data with DWARF unwind stacks:
(TODO fix perf diff)

  current code:
   5.84%     perf  perf                       [.] perf_reg_value
  change:
   1.94%     perf  perf                       [.] perf_reg_value

And little bit of overall speed up:
(perf stat -r 5 -e '{cycles,instructions}:u' ...)

  current code:
   310,298,611,754      cycles                     ( +-  0.33% )
   439,669,689,341      instructions               ( +-  0.03% )

     188.656753166 seconds time elapsed            ( +-  0.82% )

  change:
   291,315,329,878      cycles                     ( +-  0.22% )
   391,763,485,304      instructions               ( +-  0.03%  )

     180.742249687 seconds time elapsed            ( +-  0.64% )

Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1401892622-30848-2-git-send-email-jolsa@kernel.org
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
This commit is contained in:
Jiri Olsa 2014-04-17 19:39:10 +02:00
parent 17314e2385
commit 0c4e774fad
3 changed files with 17 additions and 2 deletions

View File

@ -7,6 +7,7 @@
#include "../perf.h" #include "../perf.h"
#include "map.h" #include "map.h"
#include "build-id.h" #include "build-id.h"
#include "perf_regs.h"
struct mmap_event { struct mmap_event {
struct perf_event_header header; struct perf_event_header header;
@ -89,6 +90,10 @@ struct regs_dump {
u64 abi; u64 abi;
u64 mask; u64 mask;
u64 *regs; u64 *regs;
/* Cached values/mask filled by first register access. */
u64 cache_regs[PERF_REGS_MAX];
u64 cache_mask;
}; };
struct stack_dump { struct stack_dump {

View File

@ -1,11 +1,15 @@
#include <errno.h> #include <errno.h>
#include "perf_regs.h" #include "perf_regs.h"
#include "event.h"
int perf_reg_value(u64 *valp, struct regs_dump *regs, int id) int perf_reg_value(u64 *valp, struct regs_dump *regs, int id)
{ {
int i, idx = 0; int i, idx = 0;
u64 mask = regs->mask; u64 mask = regs->mask;
if (regs->cache_mask & (1 << id))
goto out;
if (!(mask & (1 << id))) if (!(mask & (1 << id)))
return -EINVAL; return -EINVAL;
@ -14,6 +18,10 @@ int perf_reg_value(u64 *valp, struct regs_dump *regs, int id)
idx++; idx++;
} }
*valp = regs->regs[idx]; regs->cache_mask |= (1 << id);
regs->cache_regs[id] = regs->regs[idx];
out:
*valp = regs->cache_regs[id];
return 0; return 0;
} }

View File

@ -2,7 +2,8 @@
#define __PERF_REGS_H #define __PERF_REGS_H
#include <linux/types.h> #include <linux/types.h>
#include "event.h"
struct regs_dump;
#ifdef HAVE_PERF_REGS_SUPPORT #ifdef HAVE_PERF_REGS_SUPPORT
#include <perf_regs.h> #include <perf_regs.h>
@ -11,6 +12,7 @@ int perf_reg_value(u64 *valp, struct regs_dump *regs, int id);
#else #else
#define PERF_REGS_MASK 0 #define PERF_REGS_MASK 0
#define PERF_REGS_MAX 0
static inline const char *perf_reg_name(int id __maybe_unused) static inline const char *perf_reg_name(int id __maybe_unused)
{ {