Skip to content

Commit 5bbd6ba

Browse files
Jin Yaoacmel
authored andcommitted
perf streams: Report hot streams
We show the streams separately. They are divided into different sections. 1. "Matched hot streams" 2. "Hot streams in old perf data only" 3. "Hot streams in new perf data only". For each stream, we report the cycles and hot percent (hits%). For example, cycles: 2, hits: 4.08% -------------------------- main div.c:42 compute_flag div.c:28 Signed-off-by: Jin Yao <yao.jin@linux.intel.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Link: https://lore.kernel.org/r/20201009022845.13141-7-yao.jin@linux.intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
1 parent 28904f4 commit 5bbd6ba

4 files changed

Lines changed: 141 additions & 0 deletions

File tree

tools/perf/util/callchain.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1699,3 +1699,16 @@ u64 callchain_total_hits(struct hists *hists)
16991699

17001700
return chain_hits;
17011701
}
1702+
1703+
s64 callchain_avg_cycles(struct callchain_node *cnode)
1704+
{
1705+
struct callchain_list *chain;
1706+
s64 cycles = 0;
1707+
1708+
list_for_each_entry(chain, &cnode->val, list) {
1709+
if (chain->srcline && chain->branch_count)
1710+
cycles += chain->cycles_count / chain->branch_count;
1711+
}
1712+
1713+
return cycles;
1714+
}

tools/perf/util/callchain.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,4 +305,6 @@ bool callchain_cnode_matched(struct callchain_node *base_cnode,
305305

306306
u64 callchain_total_hits(struct hists *hists);
307307

308+
s64 callchain_avg_cycles(struct callchain_node *cnode);
309+
308310
#endif /* __PERF_CALLCHAIN_H */

tools/perf/util/stream.c

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,3 +217,126 @@ void evsel_streams__match(struct evsel_streams *es_base,
217217
stream__link(base_stream, pair_stream);
218218
}
219219
}
220+
221+
static void print_callchain_pair(struct stream *base_stream, int idx,
222+
struct evsel_streams *es_base,
223+
struct evsel_streams *es_pair)
224+
{
225+
struct callchain_node *base_cnode = base_stream->cnode;
226+
struct callchain_node *pair_cnode = base_stream->pair_cnode;
227+
struct callchain_list *base_chain, *pair_chain;
228+
char buf1[512], buf2[512], cbuf1[256], cbuf2[256];
229+
char *s1, *s2;
230+
double pct;
231+
232+
printf("\nhot chain pair %d:\n", idx);
233+
234+
pct = (double)base_cnode->hit / (double)es_base->streams_hits;
235+
scnprintf(buf1, sizeof(buf1), "cycles: %ld, hits: %.2f%%",
236+
callchain_avg_cycles(base_cnode), pct * 100.0);
237+
238+
pct = (double)pair_cnode->hit / (double)es_pair->streams_hits;
239+
scnprintf(buf2, sizeof(buf2), "cycles: %ld, hits: %.2f%%",
240+
callchain_avg_cycles(pair_cnode), pct * 100.0);
241+
242+
printf("%35s\t%35s\n", buf1, buf2);
243+
244+
printf("%35s\t%35s\n",
245+
"---------------------------",
246+
"--------------------------");
247+
248+
pair_chain = list_first_entry(&pair_cnode->val,
249+
struct callchain_list,
250+
list);
251+
252+
list_for_each_entry(base_chain, &base_cnode->val, list) {
253+
if (&pair_chain->list == &pair_cnode->val)
254+
return;
255+
256+
s1 = callchain_list__sym_name(base_chain, cbuf1, sizeof(cbuf1),
257+
false);
258+
s2 = callchain_list__sym_name(pair_chain, cbuf2, sizeof(cbuf2),
259+
false);
260+
261+
scnprintf(buf1, sizeof(buf1), "%35s\t%35s", s1, s2);
262+
printf("%s\n", buf1);
263+
pair_chain = list_next_entry(pair_chain, list);
264+
}
265+
}
266+
267+
static void print_stream_callchain(struct stream *stream, int idx,
268+
struct evsel_streams *es, bool pair)
269+
{
270+
struct callchain_node *cnode = stream->cnode;
271+
struct callchain_list *chain;
272+
char buf[512], cbuf[256], *s;
273+
double pct;
274+
275+
printf("\nhot chain %d:\n", idx);
276+
277+
pct = (double)cnode->hit / (double)es->streams_hits;
278+
scnprintf(buf, sizeof(buf), "cycles: %ld, hits: %.2f%%",
279+
callchain_avg_cycles(cnode), pct * 100.0);
280+
281+
if (pair) {
282+
printf("%35s\t%35s\n", "", buf);
283+
printf("%35s\t%35s\n",
284+
"", "--------------------------");
285+
} else {
286+
printf("%35s\n", buf);
287+
printf("%35s\n", "--------------------------");
288+
}
289+
290+
list_for_each_entry(chain, &cnode->val, list) {
291+
s = callchain_list__sym_name(chain, cbuf, sizeof(cbuf), false);
292+
293+
if (pair)
294+
scnprintf(buf, sizeof(buf), "%35s\t%35s", "", s);
295+
else
296+
scnprintf(buf, sizeof(buf), "%35s", s);
297+
298+
printf("%s\n", buf);
299+
}
300+
}
301+
302+
static void callchain_streams_report(struct evsel_streams *es_base,
303+
struct evsel_streams *es_pair)
304+
{
305+
struct stream *base_stream;
306+
int i, idx = 0;
307+
308+
printf("[ Matched hot streams ]\n");
309+
for (i = 0; i < es_base->nr_streams; i++) {
310+
base_stream = &es_base->streams[i];
311+
if (base_stream->pair_cnode) {
312+
print_callchain_pair(base_stream, ++idx,
313+
es_base, es_pair);
314+
}
315+
}
316+
317+
idx = 0;
318+
printf("\n[ Hot streams in old perf data only ]\n");
319+
for (i = 0; i < es_base->nr_streams; i++) {
320+
base_stream = &es_base->streams[i];
321+
if (!base_stream->pair_cnode) {
322+
print_stream_callchain(base_stream, ++idx,
323+
es_base, false);
324+
}
325+
}
326+
327+
idx = 0;
328+
printf("\n[ Hot streams in new perf data only ]\n");
329+
for (i = 0; i < es_pair->nr_streams; i++) {
330+
base_stream = &es_pair->streams[i];
331+
if (!base_stream->pair_cnode) {
332+
print_stream_callchain(base_stream, ++idx,
333+
es_pair, true);
334+
}
335+
}
336+
}
337+
338+
void evsel_streams__report(struct evsel_streams *es_base,
339+
struct evsel_streams *es_pair)
340+
{
341+
return callchain_streams_report(es_base, es_pair);
342+
}

tools/perf/util/stream.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,7 @@ struct evsel_streams *evsel_streams__entry(struct evlist_streams *els,
3535
void evsel_streams__match(struct evsel_streams *es_base,
3636
struct evsel_streams *es_pair);
3737

38+
void evsel_streams__report(struct evsel_streams *es_base,
39+
struct evsel_streams *es_pair);
40+
3841
#endif /* __PERF_STREAM_H */

0 commit comments

Comments
 (0)