Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1665374 > unrolled thread

[PATCH v1 1/2] perf report: Check for fused instruction pair

Started byJin Yao <yao.jin@linux.intel.com>
First post2017-06-14 05:00 +0200
Last post2017-06-19 05:00 +0200
Articles 3 — 3 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  [PATCH v1 1/2] perf report: Check for fused instruction pair Jin Yao <yao.jin@linux.intel.com> - 2017-06-14 05:00 +0200
    Re: [PATCH v1 1/2] perf report: Check for fused instruction pair Arnaldo Carvalho de Melo <acme@kernel.org> - 2017-06-16 18:30 +0200
      Re: [PATCH v1 1/2] perf report: Check for fused instruction pair "Jin, Yao" <yao.jin@linux.intel.com> - 2017-06-19 05:00 +0200

#1665374 — [PATCH v1 1/2] perf report: Check for fused instruction pair

FromJin Yao <yao.jin@linux.intel.com>
Date2017-06-14 05:00 +0200
Subject[PATCH v1 1/2] perf report: Check for fused instruction pair
Message-ID<tS6Hf-7QQ-5@gated-at.bofh.it>
Macro fusion merges two instructions to a single micro-op. Intel
core platform performs this hardware optimization under limited
circumstances. For example, CMP + JCC can be "fused" and executed
/retired together. While with sampling this can result in the
sample sometimes being on the JCC and sometimes on the CMP.
So for the fused instruction pair, they could be considered
together.

In general, the fused instruction pairs are:

cmp/test/add/sub/and/inc/dec + jcc.

This patch adds a new function which checks if 2 x86 instructions
are in a "fused" pair. For non-x86 arch, the function just returns
false.

Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
---
 tools/perf/arch/x86/util/Build   |  1 +
 tools/perf/arch/x86/util/fused.c | 20 ++++++++++++++++++++
 tools/perf/util/Build            |  1 +
 tools/perf/util/fused.c          | 11 +++++++++++
 tools/perf/util/fused.h          |  8 ++++++++
 5 files changed, 41 insertions(+)
 create mode 100644 tools/perf/arch/x86/util/fused.c
 create mode 100644 tools/perf/util/fused.c
 create mode 100644 tools/perf/util/fused.h

diff --git a/tools/perf/arch/x86/util/Build b/tools/perf/arch/x86/util/Build
index f95e6f4..3809348 100644
--- a/tools/perf/arch/x86/util/Build
+++ b/tools/perf/arch/x86/util/Build
@@ -4,6 +4,7 @@ libperf-y += pmu.o
 libperf-y += kvm-stat.o
 libperf-y += perf_regs.o
 libperf-y += group.o
+libperf-y += fused.o
 
 libperf-$(CONFIG_DWARF) += dwarf-regs.o
 libperf-$(CONFIG_BPF_PROLOGUE) += dwarf-regs.o
diff --git a/tools/perf/arch/x86/util/fused.c b/tools/perf/arch/x86/util/fused.c
new file mode 100644
index 0000000..be28d22
--- /dev/null
+++ b/tools/perf/arch/x86/util/fused.c
@@ -0,0 +1,20 @@
+#include <string.h>
+#include "../../util/fused.h"
+
+bool fused_insn_pair(const char *insn1, const char *insn2)
+{
+	if (strstr(insn2, "jmp"))
+		return false;
+
+	if ((strstr(insn1, "cmp") && !strstr(insn1, "xchg")) ||
+	    strstr(insn1, "test") ||
+	    strstr(insn1, "add") ||
+	    strstr(insn1, "sub") ||
+	    strstr(insn1, "and") ||
+	    strstr(insn1, "inc") ||
+	    strstr(insn1, "dec")) {
+		return true;
+	}
+
+	return false;
+}
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index 79dea95..b83757d 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -93,6 +93,7 @@ libperf-y += drv_configs.o
 libperf-y += units.o
 libperf-y += time-utils.o
 libperf-y += expr-bison.o
+libperf-y += fused.o
 
 libperf-$(CONFIG_LIBBPF) += bpf-loader.o
 libperf-$(CONFIG_BPF_PROLOGUE) += bpf-prologue.o
diff --git a/tools/perf/util/fused.c b/tools/perf/util/fused.c
new file mode 100644
index 0000000..2cf56fa
--- /dev/null
+++ b/tools/perf/util/fused.c
@@ -0,0 +1,11 @@
+#include <linux/compiler.h>
+#include <linux/types.h>
+#include <string.h>
+
+#include "fused.h"
+
+bool __weak fused_insn_pair(const char *insn1 __maybe_unused,
+			    const char *insn2 __maybe_unused)
+{
+	return false;
+}
diff --git a/tools/perf/util/fused.h b/tools/perf/util/fused.h
new file mode 100644
index 0000000..fa26714
--- /dev/null
+++ b/tools/perf/util/fused.h
@@ -0,0 +1,8 @@
+#ifndef __PERF_FUSED_H
+#define __PERF_FUSED_H
+
+#include <linux/types.h>
+
+bool fused_insn_pair(const char *insn1, const char *insn2);
+
+#endif	/* __PERF_FUSED_H */
-- 
2.7.4

[toc] | [next] | [standalone]


#1667877

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2017-06-16 18:30 +0200
Message-ID<tT2id-2u9-11@gated-at.bofh.it>
In reply to#1665374
Em Wed, Jun 14, 2017 at 10:53:40AM +0800, Jin Yao escreveu:
> Macro fusion merges two instructions to a single micro-op. Intel
> core platform performs this hardware optimization under limited
> circumstances. For example, CMP + JCC can be "fused" and executed
> /retired together. While with sampling this can result in the
> sample sometimes being on the JCC and sometimes on the CMP.
> So for the fused instruction pair, they could be considered
> together.

doing it as a weak function that will be overriden by the host arch
doesn't work, as we also support cross-annotation. So you have to take
into account perf_evsel__env_arch(evsel), etc.

Please search for perf_evsel__env_arch(evsel) in the annotation source
files to see how it is used.

- Arnaldo
 
> In general, the fused instruction pairs are:
> 
> cmp/test/add/sub/and/inc/dec + jcc.
> 
> This patch adds a new function which checks if 2 x86 instructions
> are in a "fused" pair. For non-x86 arch, the function just returns
> false.
> 
> Signed-off-by: Jin Yao <yao.jin@linux.intel.com>
> ---
>  tools/perf/arch/x86/util/Build   |  1 +
>  tools/perf/arch/x86/util/fused.c | 20 ++++++++++++++++++++
>  tools/perf/util/Build            |  1 +
>  tools/perf/util/fused.c          | 11 +++++++++++
>  tools/perf/util/fused.h          |  8 ++++++++
>  5 files changed, 41 insertions(+)
>  create mode 100644 tools/perf/arch/x86/util/fused.c
>  create mode 100644 tools/perf/util/fused.c
>  create mode 100644 tools/perf/util/fused.h
> 
> diff --git a/tools/perf/arch/x86/util/Build b/tools/perf/arch/x86/util/Build
> index f95e6f4..3809348 100644
> --- a/tools/perf/arch/x86/util/Build
> +++ b/tools/perf/arch/x86/util/Build
> @@ -4,6 +4,7 @@ libperf-y += pmu.o
>  libperf-y += kvm-stat.o
>  libperf-y += perf_regs.o
>  libperf-y += group.o
> +libperf-y += fused.o
>  
>  libperf-$(CONFIG_DWARF) += dwarf-regs.o
>  libperf-$(CONFIG_BPF_PROLOGUE) += dwarf-regs.o
> diff --git a/tools/perf/arch/x86/util/fused.c b/tools/perf/arch/x86/util/fused.c
> new file mode 100644
> index 0000000..be28d22
> --- /dev/null
> +++ b/tools/perf/arch/x86/util/fused.c
> @@ -0,0 +1,20 @@
> +#include <string.h>
> +#include "../../util/fused.h"
> +
> +bool fused_insn_pair(const char *insn1, const char *insn2)
> +{
> +	if (strstr(insn2, "jmp"))
> +		return false;
> +
> +	if ((strstr(insn1, "cmp") && !strstr(insn1, "xchg")) ||
> +	    strstr(insn1, "test") ||
> +	    strstr(insn1, "add") ||
> +	    strstr(insn1, "sub") ||
> +	    strstr(insn1, "and") ||
> +	    strstr(insn1, "inc") ||
> +	    strstr(insn1, "dec")) {
> +		return true;
> +	}
> +
> +	return false;
> +}
> diff --git a/tools/perf/util/Build b/tools/perf/util/Build
> index 79dea95..b83757d 100644
> --- a/tools/perf/util/Build
> +++ b/tools/perf/util/Build
> @@ -93,6 +93,7 @@ libperf-y += drv_configs.o
>  libperf-y += units.o
>  libperf-y += time-utils.o
>  libperf-y += expr-bison.o
> +libperf-y += fused.o
>  
>  libperf-$(CONFIG_LIBBPF) += bpf-loader.o
>  libperf-$(CONFIG_BPF_PROLOGUE) += bpf-prologue.o
> diff --git a/tools/perf/util/fused.c b/tools/perf/util/fused.c
> new file mode 100644
> index 0000000..2cf56fa
> --- /dev/null
> +++ b/tools/perf/util/fused.c
> @@ -0,0 +1,11 @@
> +#include <linux/compiler.h>
> +#include <linux/types.h>
> +#include <string.h>
> +
> +#include "fused.h"
> +
> +bool __weak fused_insn_pair(const char *insn1 __maybe_unused,
> +			    const char *insn2 __maybe_unused)
> +{
> +	return false;
> +}
> diff --git a/tools/perf/util/fused.h b/tools/perf/util/fused.h
> new file mode 100644
> index 0000000..fa26714
> --- /dev/null
> +++ b/tools/perf/util/fused.h
> @@ -0,0 +1,8 @@
> +#ifndef __PERF_FUSED_H
> +#define __PERF_FUSED_H
> +
> +#include <linux/types.h>
> +
> +bool fused_insn_pair(const char *insn1, const char *insn2);
> +
> +#endif	/* __PERF_FUSED_H */
> -- 
> 2.7.4

[toc] | [prev] | [next] | [standalone]


#1668738

From"Jin, Yao" <yao.jin@linux.intel.com>
Date2017-06-19 05:00 +0200
Message-ID<tTV4Z-5au-5@gated-at.bofh.it>
In reply to#1667877

On 6/17/2017 12:21 AM, Arnaldo Carvalho de Melo wrote:
> Em Wed, Jun 14, 2017 at 10:53:40AM +0800, Jin Yao escreveu:
>> Macro fusion merges two instructions to a single micro-op. Intel
>> core platform performs this hardware optimization under limited
>> circumstances. For example, CMP + JCC can be "fused" and executed
>> /retired together. While with sampling this can result in the
>> sample sometimes being on the JCC and sometimes on the CMP.
>> So for the fused instruction pair, they could be considered
>> together.
> doing it as a weak function that will be overriden by the host arch
> doesn't work, as we also support cross-annotation. So you have to take
> into account perf_evsel__env_arch(evsel), etc.
>
> Please search for perf_evsel__env_arch(evsel) in the annotation source
> files to see how it is used.
>
> - Arnaldo
>   
Hi Arnaldo,

Thanks so much for pointing out that the weak function doesn't work.

I have changed it to arch-specific function and just send out v2 series 
for reviewing.

Thanks
Jin Yao

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web