• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (C) 2023 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15import {Plugin, PluginContextTrace, PluginDescriptor} from '../../public';
16import {addDebugSliceTrack} from '../../public';
17
18const PERF_TRACE_COUNTERS_PRECONDITION = `
19  SELECT
20    str_value
21  FROM metadata
22  WHERE
23    name = 'trace_config_pbtxt'
24    AND str_value GLOB '*ftrace_events: "perf_trace_counters/sched_switch_with_ctrs"*'
25`;
26
27class AndroidPerfTraceCounters implements Plugin {
28  async onTraceLoad(ctx: PluginContextTrace): Promise<void> {
29    const resp = await ctx.engine.query(PERF_TRACE_COUNTERS_PRECONDITION);
30    if (resp.numRows() === 0) return;
31    ctx.registerCommand({
32      id: 'dev.perfetto.AndroidPerfTraceCounters#ThreadRuntimeIPC',
33      name: 'Add a track to show a thread runtime ipc',
34      callback: async (tid) => {
35        if (tid === undefined) {
36          tid = prompt('Enter a thread tid', '');
37          if (tid === null) return;
38        }
39        const sqlPrefix = `
40          WITH
41            sched_switch_ipc AS (
42              SELECT
43                ts,
44                EXTRACT_ARG(arg_set_id, 'prev_pid') AS tid,
45                EXTRACT_ARG(arg_set_id, 'prev_comm') AS thread_name,
46                EXTRACT_ARG(arg_set_id, 'inst') / (EXTRACT_ARG(arg_set_id, 'cyc') * 1.0) AS ipc,
47                EXTRACT_ARG(arg_set_id, 'inst') AS instruction,
48                EXTRACT_ARG(arg_set_id, 'cyc') AS cycle,
49                EXTRACT_ARG(arg_set_id, 'stallbm') AS stall_backend_mem,
50                EXTRACT_ARG(arg_set_id, 'l3dm') AS l3_cache_miss
51              FROM ftrace_event
52              WHERE name = 'sched_switch_with_ctrs' AND tid = ${tid}
53            ),
54            target_thread_sched_slice AS (
55              SELECT s.*, t.tid, t.name FROM sched s LEFT JOIN thread t USING (utid)
56                WHERE t.tid = ${tid}
57            ),
58            target_thread_ipc_slice AS (
59              SELECT
60                (
61                  SELECT
62                    ts
63                  FROM target_thread_sched_slice ts
64                  WHERE ts.tid = ssi.tid AND ts.ts < ssi.ts
65                  ORDER BY ts.ts DESC
66                  LIMIT 1
67                ) AS ts,
68                (
69                  SELECT
70                    dur
71                  FROM target_thread_sched_slice ts
72                  WHERE ts.tid = ssi.tid AND ts.ts < ssi.ts
73                  ORDER BY ts.ts DESC
74                  LIMIT 1
75                ) AS dur,
76                ssi.ipc,
77                ssi.instruction,
78                ssi.cycle,
79                ssi.stall_backend_mem,
80                ssi.l3_cache_miss
81              FROM sched_switch_ipc ssi
82            )
83        `;
84
85        await addDebugSliceTrack(
86          ctx,
87          {
88            sqlSource:
89              sqlPrefix +
90              `
91              SELECT * FROM target_thread_ipc_slice WHERE ts IS NOT NULL`,
92          },
93          'Rutime IPC:' + tid,
94          {ts: 'ts', dur: 'dur', name: 'ipc'},
95          ['instruction', 'cycle', 'stall_backend_mem', 'l3_cache_miss'],
96        );
97        ctx.tabs.openQuery(
98          sqlPrefix +
99            `
100            SELECT
101              (sum(instruction) * 1.0 / sum(cycle)*1.0) AS avg_ipc,
102              sum(dur)/1e6 as total_runtime_ms,
103              sum(instruction) AS total_instructions,
104              sum(cycle) AS total_cycles,
105              sum(stall_backend_mem) as total_stall_backend_mem,
106              sum(l3_cache_miss) as total_l3_cache_miss
107            FROM target_thread_ipc_slice WHERE ts IS NOT NULL`,
108          'target thread ipc statistic',
109        );
110      },
111    });
112  }
113}
114
115export const plugin: PluginDescriptor = {
116  pluginId: 'dev.perfetto.AndroidPerfTraceCounters',
117  plugin: AndroidPerfTraceCounters,
118};
119