Re: [PATCH v1 8/9] perf diff: Print the basic block cycles diff

2019-05-23 Thread Jin, Yao




On 5/22/2019 10:04 PM, Jiri Olsa wrote:

On Mon, May 20, 2019 at 09:27:55PM +0800, Jin Yao wrote:

Currently we only support sorting by diff cycles.

For example,

perf record -b ./div
perf record -b ./div
perf diff --basic-block

  # Cycles diff  Basic block (start:end)
  # ...  ...
  #
   -20   native_write_msr (7fff9a069900:7fff9a06990b)
-3   __indirect_thunk_start (7fff9ac02ca0:7fff9ac02ca0)
 1   __indirect_thunk_start (7fff9ac02cac:7fff9ac02cb0)
 0   rand@plt (490:490)
 0   rand (3af60:3af64)
 0   rand (3af69:3af6d)
 0   main (4e8:4ea)
 0   main (4ef:500)
 0   main (4ef:535)
 0   compute_flag (640:644)
 0   compute_flag (649:659)
 0   __random_r (3ac40:3ac76)
 0   __random_r (3ac40:3ac88)
 0   __random_r (3ac90:3ac9c)
 0   __random (3aac0:3aad2)
 0   __random (3aae0:3aae7)
 0   __random (3ab03:3ab0f)
 0   __random (3ab14:3ab1b)
 0   __random (3ab28:3ab2e)
 0   __random (3ab4a:3ab53)


really nice, could you keep the standard diff format
and display the 'Baseline' and Shared Object columns?

jirka



Thanks Jiri!

Let me check how to do that.

Thanks
Jin Yao



Signed-off-by: Jin Yao 
---
  tools/perf/builtin-diff.c | 168 ++
  tools/perf/util/hist.c|   2 +-
  tools/perf/util/sort.h|   1 +
  3 files changed, 170 insertions(+), 1 deletion(-)

diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 47e34a3..dbf242d 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -27,6 +27,12 @@
  #include 
  #include 
  
+struct block_hpp_fmt {

+   struct perf_hpp_fmt fmt;
+   struct data__file   *file;
+   int width;
+};
+
  struct block_hists {
struct histssym_hists;
struct perf_hpp_listsym_list;
@@ -34,6 +40,8 @@ struct block_hists {
struct histshists;
struct perf_hpp_listlist;
struct perf_hpp_fmt fmt;
+   struct block_hpp_fmtblock_fmt;
+   struct perf_hpp_fmt desc_fmt;
  };
  
  struct perf_diff {

@@ -1157,6 +1165,162 @@ static void compute_block_hists_diff(struct block_hists 
*block_hists,
}
  }
  
+static int64_t block_cycles_diff_cmp(struct perf_hpp_fmt *fmt,

+struct hist_entry *left,
+struct hist_entry *right)
+{
+   struct block_hpp_fmt *block_fmt = container_of(fmt,
+  struct block_hpp_fmt,
+  fmt);
+   struct data__file *d = block_fmt->file;
+   bool pairs_left  = hist_entry__has_pairs(left);
+   bool pairs_right = hist_entry__has_pairs(right);
+   struct hist_entry *p_right, *p_left;
+   s64 l, r;
+
+   if (!pairs_left && !pairs_right)
+   return 0;
+
+   if (!pairs_left || !pairs_right)
+   return pairs_left ? -1 : 1;
+
+   p_left  = get_pair_data(left, d);
+   p_right  = get_pair_data(right, d);
+
+   if (!p_left && !p_right)
+   return 0;
+
+   if (!p_left || !p_right)
+   return p_left ?  -1 : 1;
+
+   l = abs(p_left->diff.cycles_diff);
+   r = abs(p_right->diff.cycles_diff);
+
+   return r - l;
+}
+
+static int64_t block_diff_sort(struct perf_hpp_fmt *fmt,
+  struct hist_entry *left, struct hist_entry 
*right)
+{
+   return block_cycles_diff_cmp(fmt, right, left);
+}
+
+static int block_diff_header(struct perf_hpp_fmt *fmt __maybe_unused,
+struct perf_hpp *hpp,
+struct hists *hists __maybe_unused,
+int line __maybe_unused,
+int *span __maybe_unused)
+{
+   return scnprintf(hpp->buf, hpp->size, "Cycles diff");
+}
+
+static int block_diff_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
+   struct hist_entry *he)
+{
+   struct block_hpp_fmt *block_fmt = container_of(fmt,
+  struct block_hpp_fmt,
+  fmt);
+   struct data__file *d = block_fmt->file;
+   struct hist_entry *pair = get_pair_data(he, d);
+
+   if (pair && pair->diff.computed) {
+   return scnprintf(hpp->buf, hpp->size, "%*ld", block_fmt->width,
+pair->diff.cycles_diff);
+   }
+
+   return scnprintf(hpp->buf, hpp->size, "%*s", block_fmt->width, " ");
+}
+
+static int block_diff_width(struct perf_hpp_fmt *fmt,
+   struct perf_hpp *hpp __maybe_unused,
+   struct hists *hists 

Re: [PATCH v1 8/9] perf diff: Print the basic block cycles diff

2019-05-22 Thread Jiri Olsa
On Mon, May 20, 2019 at 09:27:55PM +0800, Jin Yao wrote:
> Currently we only support sorting by diff cycles.
> 
> For example,
> 
> perf record -b ./div
> perf record -b ./div
> perf diff --basic-block
> 
>  # Cycles diff  Basic block (start:end)
>  # ...  ...
>  #
>   -20   native_write_msr (7fff9a069900:7fff9a06990b)
>-3   __indirect_thunk_start (7fff9ac02ca0:7fff9ac02ca0)
> 1   __indirect_thunk_start (7fff9ac02cac:7fff9ac02cb0)
> 0   rand@plt (490:490)
> 0   rand (3af60:3af64)
> 0   rand (3af69:3af6d)
> 0   main (4e8:4ea)
> 0   main (4ef:500)
> 0   main (4ef:535)
> 0   compute_flag (640:644)
> 0   compute_flag (649:659)
> 0   __random_r (3ac40:3ac76)
> 0   __random_r (3ac40:3ac88)
> 0   __random_r (3ac90:3ac9c)
> 0   __random (3aac0:3aad2)
> 0   __random (3aae0:3aae7)
> 0   __random (3ab03:3ab0f)
> 0   __random (3ab14:3ab1b)
> 0   __random (3ab28:3ab2e)
> 0   __random (3ab4a:3ab53)

really nice, could you keep the standard diff format
and display the 'Baseline' and Shared Object columns?

jirka

> 
> Signed-off-by: Jin Yao 
> ---
>  tools/perf/builtin-diff.c | 168 
> ++
>  tools/perf/util/hist.c|   2 +-
>  tools/perf/util/sort.h|   1 +
>  3 files changed, 170 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
> index 47e34a3..dbf242d 100644
> --- a/tools/perf/builtin-diff.c
> +++ b/tools/perf/builtin-diff.c
> @@ -27,6 +27,12 @@
>  #include 
>  #include 
>  
> +struct block_hpp_fmt {
> + struct perf_hpp_fmt fmt;
> + struct data__file   *file;
> + int width;
> +};
> +
>  struct block_hists {
>   struct histssym_hists;
>   struct perf_hpp_listsym_list;
> @@ -34,6 +40,8 @@ struct block_hists {
>   struct histshists;
>   struct perf_hpp_listlist;
>   struct perf_hpp_fmt fmt;
> + struct block_hpp_fmtblock_fmt;
> + struct perf_hpp_fmt desc_fmt;
>  };
>  
>  struct perf_diff {
> @@ -1157,6 +1165,162 @@ static void compute_block_hists_diff(struct 
> block_hists *block_hists,
>   }
>  }
>  
> +static int64_t block_cycles_diff_cmp(struct perf_hpp_fmt *fmt,
> +  struct hist_entry *left,
> +  struct hist_entry *right)
> +{
> + struct block_hpp_fmt *block_fmt = container_of(fmt,
> +struct block_hpp_fmt,
> +fmt);
> + struct data__file *d = block_fmt->file;
> + bool pairs_left  = hist_entry__has_pairs(left);
> + bool pairs_right = hist_entry__has_pairs(right);
> + struct hist_entry *p_right, *p_left;
> + s64 l, r;
> +
> + if (!pairs_left && !pairs_right)
> + return 0;
> +
> + if (!pairs_left || !pairs_right)
> + return pairs_left ? -1 : 1;
> +
> + p_left  = get_pair_data(left, d);
> + p_right  = get_pair_data(right, d);
> +
> + if (!p_left && !p_right)
> + return 0;
> +
> + if (!p_left || !p_right)
> + return p_left ?  -1 : 1;
> +
> + l = abs(p_left->diff.cycles_diff);
> + r = abs(p_right->diff.cycles_diff);
> +
> + return r - l;
> +}
> +
> +static int64_t block_diff_sort(struct perf_hpp_fmt *fmt,
> +struct hist_entry *left, struct hist_entry 
> *right)
> +{
> + return block_cycles_diff_cmp(fmt, right, left);
> +}
> +
> +static int block_diff_header(struct perf_hpp_fmt *fmt __maybe_unused,
> +  struct perf_hpp *hpp,
> +  struct hists *hists __maybe_unused,
> +  int line __maybe_unused,
> +  int *span __maybe_unused)
> +{
> + return scnprintf(hpp->buf, hpp->size, "Cycles diff");
> +}
> +
> +static int block_diff_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
> + struct hist_entry *he)
> +{
> + struct block_hpp_fmt *block_fmt = container_of(fmt,
> +struct block_hpp_fmt,
> +fmt);
> + struct data__file *d = block_fmt->file;
> + struct hist_entry *pair = get_pair_data(he, d);
> +
> + if (pair && pair->diff.computed) {
> + return scnprintf(hpp->buf, hpp->size, "%*ld", block_fmt->width,
> +  pair->diff.cycles_diff);
> + }
> +
> + return scnprintf(hpp->buf, hpp->size, "%*s", block_fmt->width, " ");
> +}
> +
> +static int block_diff_width(struct perf_hpp_fmt *fmt,
> + struct perf_hpp *hpp __maybe_unused,
> + 

[PATCH v1 8/9] perf diff: Print the basic block cycles diff

2019-05-19 Thread Jin Yao
Currently we only support sorting by diff cycles.

For example,

perf record -b ./div
perf record -b ./div
perf diff --basic-block

 # Cycles diff  Basic block (start:end)
 # ...  ...
 #
  -20   native_write_msr (7fff9a069900:7fff9a06990b)
   -3   __indirect_thunk_start (7fff9ac02ca0:7fff9ac02ca0)
1   __indirect_thunk_start (7fff9ac02cac:7fff9ac02cb0)
0   rand@plt (490:490)
0   rand (3af60:3af64)
0   rand (3af69:3af6d)
0   main (4e8:4ea)
0   main (4ef:500)
0   main (4ef:535)
0   compute_flag (640:644)
0   compute_flag (649:659)
0   __random_r (3ac40:3ac76)
0   __random_r (3ac40:3ac88)
0   __random_r (3ac90:3ac9c)
0   __random (3aac0:3aad2)
0   __random (3aae0:3aae7)
0   __random (3ab03:3ab0f)
0   __random (3ab14:3ab1b)
0   __random (3ab28:3ab2e)
0   __random (3ab4a:3ab53)

Signed-off-by: Jin Yao 
---
 tools/perf/builtin-diff.c | 168 ++
 tools/perf/util/hist.c|   2 +-
 tools/perf/util/sort.h|   1 +
 3 files changed, 170 insertions(+), 1 deletion(-)

diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 47e34a3..dbf242d 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -27,6 +27,12 @@
 #include 
 #include 
 
+struct block_hpp_fmt {
+   struct perf_hpp_fmt fmt;
+   struct data__file   *file;
+   int width;
+};
+
 struct block_hists {
struct histssym_hists;
struct perf_hpp_listsym_list;
@@ -34,6 +40,8 @@ struct block_hists {
struct histshists;
struct perf_hpp_listlist;
struct perf_hpp_fmt fmt;
+   struct block_hpp_fmtblock_fmt;
+   struct perf_hpp_fmt desc_fmt;
 };
 
 struct perf_diff {
@@ -1157,6 +1165,162 @@ static void compute_block_hists_diff(struct block_hists 
*block_hists,
}
 }
 
+static int64_t block_cycles_diff_cmp(struct perf_hpp_fmt *fmt,
+struct hist_entry *left,
+struct hist_entry *right)
+{
+   struct block_hpp_fmt *block_fmt = container_of(fmt,
+  struct block_hpp_fmt,
+  fmt);
+   struct data__file *d = block_fmt->file;
+   bool pairs_left  = hist_entry__has_pairs(left);
+   bool pairs_right = hist_entry__has_pairs(right);
+   struct hist_entry *p_right, *p_left;
+   s64 l, r;
+
+   if (!pairs_left && !pairs_right)
+   return 0;
+
+   if (!pairs_left || !pairs_right)
+   return pairs_left ? -1 : 1;
+
+   p_left  = get_pair_data(left, d);
+   p_right  = get_pair_data(right, d);
+
+   if (!p_left && !p_right)
+   return 0;
+
+   if (!p_left || !p_right)
+   return p_left ?  -1 : 1;
+
+   l = abs(p_left->diff.cycles_diff);
+   r = abs(p_right->diff.cycles_diff);
+
+   return r - l;
+}
+
+static int64_t block_diff_sort(struct perf_hpp_fmt *fmt,
+  struct hist_entry *left, struct hist_entry 
*right)
+{
+   return block_cycles_diff_cmp(fmt, right, left);
+}
+
+static int block_diff_header(struct perf_hpp_fmt *fmt __maybe_unused,
+struct perf_hpp *hpp,
+struct hists *hists __maybe_unused,
+int line __maybe_unused,
+int *span __maybe_unused)
+{
+   return scnprintf(hpp->buf, hpp->size, "Cycles diff");
+}
+
+static int block_diff_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
+   struct hist_entry *he)
+{
+   struct block_hpp_fmt *block_fmt = container_of(fmt,
+  struct block_hpp_fmt,
+  fmt);
+   struct data__file *d = block_fmt->file;
+   struct hist_entry *pair = get_pair_data(he, d);
+
+   if (pair && pair->diff.computed) {
+   return scnprintf(hpp->buf, hpp->size, "%*ld", block_fmt->width,
+pair->diff.cycles_diff);
+   }
+
+   return scnprintf(hpp->buf, hpp->size, "%*s", block_fmt->width, " ");
+}
+
+static int block_diff_width(struct perf_hpp_fmt *fmt,
+   struct perf_hpp *hpp __maybe_unused,
+   struct hists *hists __maybe_unused)
+{
+   struct block_hpp_fmt *block_fmt =
+   container_of(fmt, struct block_hpp_fmt, fmt);
+
+   return block_fmt->width;
+}
+
+static int block_sym_width(struct perf_hpp_fmt *fmt __maybe_unused,
+   struct perf_hpp *hpp __maybe_unused,
+   struct