2021-09-06 16:10:48

by Adrian Hunter

[permalink] [raw]
Subject: [PATCH] perf dlfilter: Add dlfilter-show-cycles

Add a new dlfilter to show cycles.

Cycle counts are accumulated per CPU (or per thread if CPU is not recorded)
from IPC information, and printed together with the change since the last
print, at the start of each line.

Signed-off-by: Adrian Hunter <[email protected]>
---
tools/perf/Makefile.perf | 2 +-
tools/perf/dlfilters/dlfilter-show-cycles.c | 107 ++++++++++++++++++++
2 files changed, 108 insertions(+), 1 deletion(-)
create mode 100644 tools/perf/dlfilters/dlfilter-show-cycles.c

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index e04313c4d840..6b2c8b46ea80 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -360,7 +360,7 @@ ifndef NO_JVMTI
PROGRAMS += $(OUTPUT)$(LIBJVMTI)
endif

-DLFILTERS := dlfilter-test-api-v0.so
+DLFILTERS := dlfilter-test-api-v0.so dlfilter-show-cycles.so
DLFILTERS := $(patsubst %,$(OUTPUT)dlfilters/%,$(DLFILTERS))

# what 'all' will build and 'install' will install, in perfexecdir
diff --git a/tools/perf/dlfilters/dlfilter-show-cycles.c b/tools/perf/dlfilters/dlfilter-show-cycles.c
new file mode 100644
index 000000000000..d5b37f560ffd
--- /dev/null
+++ b/tools/perf/dlfilters/dlfilter-show-cycles.c
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * dlfilter-show-cycles.c: Print the number of cycles at the start of each line
+ * Copyright (c) 2021, Intel Corporation.
+ */
+#include <perf/perf_dlfilter.h>
+#include <stdio.h>
+
+#define MAX_CPU 4096
+
+static __u64 cycles[MAX_CPU];
+static __u64 cycles_rpt[MAX_CPU];
+
+#define BITS 16
+#define TABLESZ (1 << BITS)
+#define TABLEMAX (TABLESZ / 2)
+#define MASK (TABLESZ - 1)
+
+static struct entry {
+ __u32 used;
+ __s32 tid;
+ __u64 cycles;
+ __u64 cycles_rpt;
+} table[TABLESZ];
+
+static int tid_cnt;
+
+static struct entry *find_entry(__s32 tid)
+{
+ __u32 pos = tid & MASK;
+ struct entry *e;
+
+ e = &table[pos];
+ while (e->used) {
+ if (e->tid == tid)
+ return e;
+ if (++pos == TABLESZ)
+ pos = 0;
+ e = &table[pos];
+ }
+
+ if (tid_cnt >= TABLEMAX) {
+ fprintf(stderr, "Too many threads\n");
+ return NULL;
+ }
+
+ tid_cnt += 1;
+ e->used = 1;
+ e->tid = tid;
+ return e;
+}
+
+static void add_entry(__s32 tid, __u64 cnt)
+{
+ struct entry *e = find_entry(tid);
+
+ if (e)
+ e->cycles += cnt;
+}
+
+int filter_event_early(void *data, const struct perf_dlfilter_sample *sample, void *ctx)
+{
+ __s32 cpu = sample->cpu;
+ __s32 tid = sample->tid;
+
+ if (cpu >= 0 && cpu < MAX_CPU)
+ cycles[cpu] += sample->cyc_cnt;
+ else if (tid != -1)
+ add_entry(tid, sample->cyc_cnt);
+ return 0;
+}
+
+int filter_event(void *data, const struct perf_dlfilter_sample *sample, void *ctx)
+{
+ __s32 cpu = sample->cpu;
+ __s32 tid = sample->tid;
+
+ if (cpu >= 0 && cpu < MAX_CPU) {
+ printf("%10llu %10llu ", cycles[cpu], cycles[cpu] - cycles_rpt[cpu]);
+ cycles_rpt[cpu] = cycles[cpu];
+ return 0;
+ }
+
+ if (tid != -1) {
+ struct entry *e = find_entry(tid);
+
+ if (e) {
+ printf("%10llu %10llu ", e->cycles, e->cycles - e->cycles_rpt);
+ e->cycles_rpt = e->cycles;
+ return 0;
+ }
+ }
+
+ printf("%22s", "");
+ return 0;
+}
+
+const char *filter_description(const char **long_description)
+{
+ static char *long_desc = "Cycle counts are accumulated per CPU (or "
+ "per thread if CPU is not recorded) from IPC information, and "
+ "printed together with the change since the last print, at the "
+ "start of each line.";
+
+ *long_description = long_desc;
+ return "Print the number of cycles at the start of each line";
+}
--
2.17.1


2021-09-07 02:58:14

by Andi Kleen

[permalink] [raw]
Subject: Re: [PATCH] perf dlfilter: Add dlfilter-show-cycles


On 9/6/2021 9:08 AM, Adrian Hunter wrote:
> Add a new dlfilter to show cycles.
>
> Cycle counts are accumulated per CPU (or per thread if CPU is not recorded)
> from IPC information, and printed together with the change since the last
> print, at the start of each line.


Thanks! An example how to use it would be nice (but maybe Arnaldo will
just add that with his usual testing comment). And I guess the linear
search could be a problem at some point, but I guess it's good enough
for now.

Reviewed-by: Andi Kleen <[email protected]>


2021-09-07 07:21:01

by Adrian Hunter

[permalink] [raw]
Subject: Re: [PATCH] perf dlfilter: Add dlfilter-show-cycles

On 7/09/21 5:54 am, Andi Kleen wrote:
>
> On 9/6/2021 9:08 AM, Adrian Hunter wrote:
>> Add a new dlfilter to show cycles.
>>
>> Cycle counts are accumulated per CPU (or per thread if CPU is not recorded)
>> from IPC information, and printed together with the change since the last
>> print, at the start of each line.
>
>
> Thanks! An example how to use it would be nice

I started looking at making an example and noticed that this approach
does not work very well because the IPC cycle count only increases when
the IPC is output which (for CYC accurate mode) is only happens when a
CYC packet is output that corresponds to the current sample. Seems like
this needs a re-think, sorry.

2021-09-08 17:46:36

by Arnaldo Carvalho de Melo

[permalink] [raw]
Subject: Re: [PATCH] perf dlfilter: Add dlfilter-show-cycles

Em Tue, Sep 07, 2021 at 10:06:03AM +0300, Adrian Hunter escreveu:
> On 7/09/21 5:54 am, Andi Kleen wrote:
> > On 9/6/2021 9:08 AM, Adrian Hunter wrote:
> >> Add a new dlfilter to show cycles.

> >> Cycle counts are accumulated per CPU (or per thread if CPU is not recorded)
> >> from IPC information, and printed together with the change since the last
> >> print, at the start of each line.

> > Thanks! An example how to use it would be nice

> I started looking at making an example and noticed that this approach
> does not work very well because the IPC cycle count only increases when
> the IPC is output which (for CYC accurate mode) is only happens when a
> CYC packet is output that corresponds to the current sample. Seems like
> this needs a re-think, sorry.

Ok, will wait then. And this shows part of the value of this, checking
if it works as expected :-)

- Arnaldo