aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/scripts/python/stat-cpi.py
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@kernel.org>2016-01-06 05:49:57 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2016-01-06 18:11:16 -0500
commitb8a1962d17b4e3cfdd7b7dc9ebd94affbcb4c1c5 (patch)
tree17faa8f8e699e7e1bdd0bf1fafb8d89a51210e0b /tools/perf/scripts/python/stat-cpi.py
parent36e33c53f4b693d96fb8dd4529fe14306d4e3e76 (diff)
perf script: Add stat-cpi.py script
Adding stat-cpi.py as an example of how to do stat scripting. It computes the CPI metrics from cycles and instructions events. The CPI is based performance metric showing the Cycles Per Instructions ratio, which helps to identify cycles-hungry code. Following stat record/report/script combinations could be used: - get CPI for given workload $ perf stat -e cycles,instructions record ls SNIP Performance counter stats for 'ls': 2,904,431 cycles 3,346,878 instructions # 1.15 insns per cycle 0.001782686 seconds time elapsed $ perf script -s ./scripts/python/stat-cpi.py 0.001783: cpu -1, thread -1 -> cpi 0.867803 (2904431/3346878) $ perf stat -e cycles,instructions record ls | perf script -s ./scripts/python/stat-cpi.py SNIP 0.001730: cpu -1, thread -1 -> cpi 0.869026 (2928292/3369627) - get CPI systemwide: $ perf stat -e cycles,instructions -a -I 1000 record sleep 3 # time counts unit events 1.000158618 594,274,711 cycles (100.00%) 1.000158618 441,898,250 instructions 2.000350973 567,649,705 cycles (100.00%) 2.000350973 432,669,206 instructions 3.000559210 561,940,430 cycles (100.00%) 3.000559210 420,403,465 instructions 3.000670798 780,105 cycles (100.00%) 3.000670798 326,516 instructions $ perf script -s ./scripts/python/stat-cpi.py 1.000159: cpu -1, thread -1 -> cpi 1.344823 (594274711/441898250) 2.000351: cpu -1, thread -1 -> cpi 1.311972 (567649705/432669206) 3.000559: cpu -1, thread -1 -> cpi 1.336669 (561940430/420403465) 3.000671: cpu -1, thread -1 -> cpi 2.389178 (780105/326516) $ perf stat -e cycles,instructions -a -I 1000 record sleep 3 | perf script -s ./scripts/python/stat-cpi.py 1.000202: cpu -1, thread -1 -> cpi 1.035091 (940778881/908885530) 2.000392: cpu -1, thread -1 -> cpi 1.442600 (627493992/434974455) 3.000545: cpu -1, thread -1 -> cpi 1.353612 (741463930/547766890) 3.000622: cpu -1, thread -1 -> cpi 2.642110 (784083/296764) Signed-off-by: Jiri Olsa <jolsa@kernel.org> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Tested-by: Kan Liang <kan.liang@intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1452077397-31958-4-git-send-email-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/scripts/python/stat-cpi.py')
-rw-r--r--tools/perf/scripts/python/stat-cpi.py77
1 files changed, 77 insertions, 0 deletions
diff --git a/tools/perf/scripts/python/stat-cpi.py b/tools/perf/scripts/python/stat-cpi.py
new file mode 100644
index 000000000000..8b60f343dd07
--- /dev/null
+++ b/tools/perf/scripts/python/stat-cpi.py
@@ -0,0 +1,77 @@
1#!/usr/bin/env python
2
3data = {}
4times = []
5threads = []
6cpus = []
7
8def get_key(time, event, cpu, thread):
9 return "%d-%s-%d-%d" % (time, event, cpu, thread)
10
11def store_key(time, cpu, thread):
12 if (time not in times):
13 times.append(time)
14
15 if (cpu not in cpus):
16 cpus.append(cpu)
17
18 if (thread not in threads):
19 threads.append(thread)
20
21def store(time, event, cpu, thread, val, ena, run):
22 #print "event %s cpu %d, thread %d, time %d, val %d, ena %d, run %d" % \
23 # (event, cpu, thread, time, val, ena, run)
24
25 store_key(time, cpu, thread)
26 key = get_key(time, event, cpu, thread)
27 data[key] = [ val, ena, run]
28
29def get(time, event, cpu, thread):
30 key = get_key(time, event, cpu, thread)
31 return data[key][0]
32
33def stat__cycles_k(cpu, thread, time, val, ena, run):
34 store(time, "cycles", cpu, thread, val, ena, run);
35
36def stat__instructions_k(cpu, thread, time, val, ena, run):
37 store(time, "instructions", cpu, thread, val, ena, run);
38
39def stat__cycles_u(cpu, thread, time, val, ena, run):
40 store(time, "cycles", cpu, thread, val, ena, run);
41
42def stat__instructions_u(cpu, thread, time, val, ena, run):
43 store(time, "instructions", cpu, thread, val, ena, run);
44
45def stat__cycles(cpu, thread, time, val, ena, run):
46 store(time, "cycles", cpu, thread, val, ena, run);
47
48def stat__instructions(cpu, thread, time, val, ena, run):
49 store(time, "instructions", cpu, thread, val, ena, run);
50
51def stat__interval(time):
52 for cpu in cpus:
53 for thread in threads:
54 cyc = get(time, "cycles", cpu, thread)
55 ins = get(time, "instructions", cpu, thread)
56 cpi = 0
57
58 if ins != 0:
59 cpi = cyc/float(ins)
60
61 print "%15f: cpu %d, thread %d -> cpi %f (%d/%d)" % (time/(float(1000000000)), cpu, thread, cpi, cyc, ins)
62
63def trace_end():
64 pass
65# XXX trace_end callback could be used as an alternative place
66# to compute same values as in the script above:
67#
68# for time in times:
69# for cpu in cpus:
70# for thread in threads:
71# cyc = get(time, "cycles", cpu, thread)
72# ins = get(time, "instructions", cpu, thread)
73#
74# if ins != 0:
75# cpi = cyc/float(ins)
76#
77# print "time %.9f, cpu %d, thread %d -> cpi %f" % (time/(float(1000000000)), cpu, thread, cpi)