• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1--
2-- Copyright 2024 The Android Open Source Project
3--
4-- Licensed under the Apache License, Version 2.0 (the "License");
5-- you may not use this file except in compliance with the License.
6-- You may obtain a copy of the License at
7--
8--     https://www.apache.org/licenses/LICENSE-2.0
9--
10-- Unless required by applicable law or agreed to in writing, software
11-- distributed under the License is distributed on an "AS IS" BASIS,
12-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-- See the License for the specific language governing permissions and
14-- limitations under the License.
15
16INCLUDE PERFETTO MODULE android.suspend;
17
18INCLUDE PERFETTO MODULE intervals.intersect;
19
20INCLUDE PERFETTO MODULE time.conversion;
21
22INCLUDE PERFETTO MODULE wattson.arm_dsu;
23
24INCLUDE PERFETTO MODULE wattson.cpu_freq_idle;
25
26INCLUDE PERFETTO MODULE wattson.curves.utils;
27
28INCLUDE PERFETTO MODULE wattson.device_infos;
29
30-- Helper macro to do pivot function without policy information
31CREATE PERFETTO MACRO _stats_wo_policy_subquery(
32    cpu Expr,
33    curve_col ColumnName,
34    freq_col ColumnName,
35    idle_col ColumnName
36)
37RETURNS TableOrSubquery AS
38(
39  SELECT
40    ts,
41    dur,
42    curve_value AS $curve_col,
43    freq AS $freq_col,
44    idle AS $idle_col
45  FROM _idle_freq_materialized
46  WHERE
47    cpu = $cpu
48);
49
50-- Helper macro to do pivot function with policy information
51CREATE PERFETTO MACRO _stats_w_policy_subquery(
52    cpu Expr,
53    policy_col ColumnName,
54    curve_col ColumnName,
55    freq_col ColumnName,
56    idle_col ColumnName
57)
58RETURNS TableOrSubquery AS
59(
60  SELECT
61    ts,
62    dur,
63    policy AS $policy_col,
64    curve_value AS $curve_col,
65    freq AS $freq_col,
66    idle AS $idle_col
67  FROM _idle_freq_materialized
68  WHERE
69    cpu = $cpu
70);
71
72CREATE PERFETTO TABLE _stats_cpu0 AS
73SELECT
74  *
75FROM _stats_wo_policy_subquery!(0, cpu0_curve, freq_0, idle_0);
76
77CREATE PERFETTO TABLE _stats_cpu1 AS
78SELECT
79  *
80FROM _stats_wo_policy_subquery!(1, cpu1_curve, freq_1, idle_1);
81
82CREATE PERFETTO TABLE _stats_cpu2 AS
83SELECT
84  *
85FROM _stats_wo_policy_subquery!(2, cpu2_curve, freq_2, idle_2);
86
87CREATE PERFETTO TABLE _stats_cpu3 AS
88SELECT
89  *
90FROM _stats_wo_policy_subquery!(3, cpu3_curve, freq_3, idle_3);
91
92CREATE PERFETTO TABLE _stats_cpu4 AS
93SELECT
94  *
95FROM _stats_w_policy_subquery!(4, policy_4, cpu4_curve, freq_4, idle_4);
96
97CREATE PERFETTO TABLE _stats_cpu5 AS
98SELECT
99  *
100FROM _stats_w_policy_subquery!(5, policy_5, cpu5_curve, freq_5, idle_5);
101
102CREATE PERFETTO TABLE _stats_cpu6 AS
103SELECT
104  *
105FROM _stats_w_policy_subquery!(6, policy_6, cpu6_curve, freq_6, idle_6);
106
107CREATE PERFETTO TABLE _stats_cpu7 AS
108SELECT
109  *
110FROM _stats_w_policy_subquery!(7, policy_7, cpu7_curve, freq_7, idle_7);
111
112CREATE PERFETTO TABLE _stats_cpu0123_suspend AS
113SELECT
114  ii.ts,
115  ii.dur,
116  id_0 AS cpu0_id,
117  id_1 AS cpu1_id,
118  id_2 AS cpu2_id,
119  id_3 AS cpu3_id,
120  ss.power_state = 'suspended' AS suspended
121FROM _interval_intersect!(
122  (
123    _ii_subquery!(_stats_cpu0),
124    _ii_subquery!(_stats_cpu1),
125    _ii_subquery!(_stats_cpu2),
126    _ii_subquery!(_stats_cpu3),
127    -- Includes suspend AND awake portions, which will cover entire trace and
128    -- allows us to use _interval_intersect instead of SPAN_OUTER_JOIN()
129    _ii_subquery!(android_suspend_state)
130  ),
131  ()
132) AS ii
133JOIN android_suspend_state AS ss
134  ON ss._auto_id = id_4;
135
136CREATE PERFETTO TABLE _stats_cpu4567 AS
137SELECT
138  ii.ts,
139  ii.dur,
140  id_0 AS cpu4_id,
141  id_1 AS cpu5_id,
142  id_2 AS cpu6_id,
143  id_3 AS cpu7_id
144FROM _interval_intersect!(
145  (
146    _ii_subquery!(_stats_cpu4),
147    _ii_subquery!(_stats_cpu5),
148    _ii_subquery!(_stats_cpu6),
149    _ii_subquery!(_stats_cpu7)
150  ),
151  ()
152) AS ii;
153
154-- SPAN OUTER JOIN because sometimes CPU4/5/6/7 are empty tables
155CREATE VIRTUAL TABLE _stats_cpu01234567_suspend USING SPAN_OUTER_JOIN (_stats_cpu0123_suspend, _stats_cpu4567);
156
157-- Combine system state so that it has idle, freq, and L3 hit info.
158CREATE VIRTUAL TABLE _idle_freq_l3_hit_slice USING SPAN_OUTER_JOIN (_stats_cpu01234567_suspend, _arm_l3_hit_rate);
159
160-- Combine system state so that it has idle, freq, L3 hit, and L3 miss info.
161CREATE VIRTUAL TABLE _idle_freq_l3_hit_l3_miss_slice USING SPAN_OUTER_JOIN (_idle_freq_l3_hit_slice, _arm_l3_miss_rate);
162
163-- Does calculations for CPUs that are independent of other CPUs or frequencies
164-- This is the last generic table before going to device specific table calcs
165CREATE PERFETTO TABLE _w_independent_cpus_calc AS
166SELECT
167  base.ts,
168  base.dur,
169  cast_int!(l3_hit_rate * base.dur) AS l3_hit_count,
170  cast_int!(l3_miss_rate * base.dur) AS l3_miss_count,
171  freq_0,
172  idle_0,
173  freq_1,
174  idle_1,
175  freq_2,
176  idle_2,
177  freq_3,
178  idle_3,
179  freq_4,
180  idle_4,
181  freq_5,
182  idle_5,
183  freq_6,
184  idle_6,
185  freq_7,
186  idle_7,
187  policy_4,
188  policy_5,
189  policy_6,
190  policy_7,
191  iif(
192    suspended,
193    1,
194    min(coalesce(idle_0, 1), coalesce(idle_1, 1), coalesce(idle_2, 1), coalesce(idle_3, 1))
195  ) AS no_static,
196  suspended,
197  cpu0_curve,
198  cpu1_curve,
199  cpu2_curve,
200  cpu3_curve,
201  cpu4_curve,
202  cpu5_curve,
203  cpu6_curve,
204  cpu7_curve,
205  -- If dependency CPUs are active, then that CPU could contribute static power
206  iif(idle_4 = -1, lut4.curve_value, -1) AS static_4,
207  iif(idle_5 = -1, lut5.curve_value, -1) AS static_5,
208  iif(idle_6 = -1, lut6.curve_value, -1) AS static_6,
209  iif(idle_7 = -1, lut7.curve_value, -1) AS static_7
210FROM _idle_freq_l3_hit_l3_miss_slice AS base
211JOIN _stats_cpu0
212  ON _stats_cpu0._auto_id = base.cpu0_id
213JOIN _stats_cpu1
214  ON _stats_cpu1._auto_id = base.cpu1_id
215JOIN _stats_cpu2
216  ON _stats_cpu2._auto_id = base.cpu2_id
217JOIN _stats_cpu3
218  ON _stats_cpu3._auto_id = base.cpu3_id
219-- Get CPU power curves for CPUs that aren't always present
220LEFT JOIN _stats_cpu4
221  ON _stats_cpu4._auto_id = base.cpu4_id
222LEFT JOIN _stats_cpu5
223  ON _stats_cpu5._auto_id = base.cpu5_id
224LEFT JOIN _stats_cpu6
225  ON _stats_cpu6._auto_id = base.cpu6_id
226LEFT JOIN _stats_cpu7
227  ON _stats_cpu7._auto_id = base.cpu7_id
228-- Match power curves if possible on CPUs that decide 2D dependence
229LEFT JOIN _filtered_curves_2d AS lut4
230  ON _stats_cpu0.freq_0 = lut4.freq_khz
231  AND _stats_cpu4.policy_4 = lut4.other_policy
232  AND _stats_cpu4.freq_4 = lut4.other_freq_khz
233  AND lut4.idle = 255
234LEFT JOIN _filtered_curves_2d AS lut5
235  ON _stats_cpu0.freq_0 = lut5.freq_khz
236  AND _stats_cpu5.policy_5 = lut5.other_policy
237  AND _stats_cpu5.freq_5 = lut5.other_freq_khz
238  AND lut5.idle = 255
239LEFT JOIN _filtered_curves_2d AS lut6
240  ON _stats_cpu0.freq_0 = lut6.freq_khz
241  AND _stats_cpu6.policy_6 = lut6.other_policy
242  AND _stats_cpu6.freq_6 = lut6.other_freq_khz
243  AND lut6.idle = 255
244LEFT JOIN _filtered_curves_2d AS lut7
245  ON _stats_cpu0.freq_0 = lut7.freq_khz
246  AND _stats_cpu7.policy_7 = lut7.other_policy
247  AND _stats_cpu7.freq_7 = lut7.other_freq_khz
248  AND lut7.idle = 255
249-- Needs to be at least 1us to reduce inconsequential rows.
250WHERE
251  base.dur > time_from_us(1);
252