• 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 wattson.cpu_split;
17
18INCLUDE PERFETTO MODULE wattson.curves.utils;
19
20INCLUDE PERFETTO MODULE wattson.curves.w_cpu_dependence;
21
22INCLUDE PERFETTO MODULE wattson.curves.w_dsu_dependence;
23
24INCLUDE PERFETTO MODULE wattson.device_infos;
25
26-- One of the two tables will be empty, depending on whether the device is
27-- dependent on devfreq or a different CPU's frequency
28CREATE PERFETTO VIEW _curves_w_dependencies (
29  ts TIMESTAMP,
30  dur DURATION,
31  freq_0 LONG,
32  idle_0 LONG,
33  freq_1 LONG,
34  idle_1 LONG,
35  freq_2 LONG,
36  idle_2 LONG,
37  freq_3 LONG,
38  idle_3 LONG,
39  cpu0_curve DOUBLE,
40  cpu1_curve DOUBLE,
41  cpu2_curve DOUBLE,
42  cpu3_curve DOUBLE,
43  cpu4_curve DOUBLE,
44  cpu5_curve DOUBLE,
45  cpu6_curve DOUBLE,
46  cpu7_curve DOUBLE,
47  l3_hit_count LONG,
48  l3_miss_count LONG,
49  suspended BOOL,
50  no_static LONG,
51  all_cpu_deep_idle LONG,
52  dependent_freq LONG,
53  dependent_policy LONG
54) AS
55-- Table that is dependent on differet CPU's frequency
56SELECT
57  *
58FROM _w_cpu_dependence
59UNION ALL
60-- Table that is dependent of devfreq frequency
61SELECT
62  *
63FROM _w_dsu_dependence;
64
65-- Final table showing the curves per CPU per slice
66CREATE PERFETTO TABLE _system_state_curves AS
67SELECT
68  base.ts,
69  base.dur,
70  -- base.cpu[0-3]_curve will be non-zero if CPU has 1D dependency
71  -- base.cpu[0-3]_curve will be zero if device is suspended or deep idle
72  -- base.cpu[0-3]_curve will be NULL if 2D dependency required
73  iif(suspended, 0.0, coalesce(base.cpu0_curve, lut0.curve_value)) AS cpu0_curve,
74  iif(suspended, 0.0, coalesce(base.cpu1_curve, lut1.curve_value)) AS cpu1_curve,
75  iif(suspended, 0.0, coalesce(base.cpu2_curve, lut2.curve_value)) AS cpu2_curve,
76  iif(suspended, 0.0, coalesce(base.cpu3_curve, lut3.curve_value)) AS cpu3_curve,
77  -- base.cpu[4-7]_curve will be non-zero if CPU has 1D dependency
78  -- base.cpu[4-7]_curve will be zero if device is suspended or deep idle
79  -- base.cpu[4-7]_curve will be NULL if CPU doesn't exist on device
80  iif(suspended, 0.0, coalesce(base.cpu4_curve, 0.0)) AS cpu4_curve,
81  iif(suspended, 0.0, coalesce(base.cpu5_curve, 0.0)) AS cpu5_curve,
82  iif(suspended, 0.0, coalesce(base.cpu6_curve, 0.0)) AS cpu6_curve,
83  iif(suspended, 0.0, coalesce(base.cpu7_curve, 0.0)) AS cpu7_curve,
84  iif(no_static = 1, 0.0, coalesce(static_1d.curve_value, static_2d.curve_value)) AS static_curve,
85  iif(all_cpu_deep_idle = 1, 0, base.l3_hit_count * l3_hit_lut.curve_value) AS l3_hit_value,
86  iif(all_cpu_deep_idle = 1, 0, base.l3_miss_count * l3_miss_lut.curve_value) AS l3_miss_value
87FROM _curves_w_dependencies AS base
88-- LUT for 2D dependencies
89LEFT JOIN _filtered_curves_2d AS lut0
90  ON lut0.freq_khz = base.freq_0
91  AND lut0.other_policy = base.dependent_policy
92  AND lut0.other_freq_khz = base.dependent_freq
93  AND lut0.idle = base.idle_0
94LEFT JOIN _filtered_curves_2d AS lut1
95  ON lut1.freq_khz = base.freq_1
96  AND lut1.other_policy = base.dependent_policy
97  AND lut1.other_freq_khz = base.dependent_freq
98  AND lut1.idle = base.idle_1
99LEFT JOIN _filtered_curves_2d AS lut2
100  ON lut2.freq_khz = base.freq_2
101  AND lut2.other_policy = base.dependent_policy
102  AND lut2.other_freq_khz = base.dependent_freq
103  AND lut2.idle = base.idle_2
104LEFT JOIN _filtered_curves_2d AS lut3
105  ON lut3.freq_khz = base.freq_3
106  AND lut3.other_policy = base.dependent_policy
107  AND lut3.other_freq_khz = base.dependent_freq
108  AND lut3.idle = base.idle_3
109-- LUT for static curve lookup
110LEFT JOIN _filtered_curves_2d AS static_2d
111  ON static_2d.freq_khz = base.freq_0
112  AND static_2d.other_policy = base.dependent_policy
113  AND static_2d.other_freq_khz = base.dependent_freq
114  AND static_2d.idle = 255
115LEFT JOIN _filtered_curves_1d AS static_1d
116  ON static_1d.policy = 0 AND static_1d.freq_khz = base.freq_0 AND static_1d.idle = 255
117-- LUT joins for L3 cache
118LEFT JOIN _filtered_curves_l3 AS l3_hit_lut
119  ON l3_hit_lut.freq_khz = base.freq_0
120  AND l3_hit_lut.other_policy = base.dependent_policy
121  AND l3_hit_lut.other_freq_khz = base.dependent_freq
122  AND l3_hit_lut.action = 'hit'
123LEFT JOIN _filtered_curves_l3 AS l3_miss_lut
124  ON l3_miss_lut.freq_khz = base.freq_0
125  AND l3_miss_lut.other_policy = base.dependent_policy
126  AND l3_miss_lut.other_freq_khz = base.dependent_freq
127  AND l3_miss_lut.action = 'miss';
128
129-- The most basic components of Wattson, all normalized to be in mW on a per
130-- system state basis
131CREATE PERFETTO TABLE _system_state_mw AS
132SELECT
133  ts,
134  dur,
135  cpu0_curve AS cpu0_mw,
136  cpu1_curve AS cpu1_mw,
137  cpu2_curve AS cpu2_mw,
138  cpu3_curve AS cpu3_mw,
139  cpu4_curve AS cpu4_mw,
140  cpu5_curve AS cpu5_mw,
141  cpu6_curve AS cpu6_mw,
142  cpu7_curve AS cpu7_mw,
143  -- LUT for l3 is scaled by 10^6 to save resolution and in units of kWs. Scale
144  -- this by 10^3 so when divided by ns, result is in units of mW
145  (
146    (
147      coalesce(l3_hit_value, 0) + coalesce(l3_miss_value, 0)
148    ) * 1000 / dur
149  ) + static_curve AS dsu_scu_mw
150FROM _system_state_curves;
151
152-- API to get power from each system state in an arbitrary time window
153CREATE PERFETTO FUNCTION _windowed_system_state_mw(
154    ts TIMESTAMP,
155    dur LONG
156)
157RETURNS TABLE (
158  cpu0_mw DOUBLE,
159  cpu1_mw DOUBLE,
160  cpu2_mw DOUBLE,
161  cpu3_mw DOUBLE,
162  cpu4_mw DOUBLE,
163  cpu5_mw DOUBLE,
164  cpu6_mw DOUBLE,
165  cpu7_mw DOUBLE,
166  dsu_scu_mw DOUBLE
167) AS
168SELECT
169  sum(ss.cpu0_mw * ss.dur) / sum(ss.dur) AS cpu0_mw,
170  sum(ss.cpu1_mw * ss.dur) / sum(ss.dur) AS cpu1_mw,
171  sum(ss.cpu2_mw * ss.dur) / sum(ss.dur) AS cpu2_mw,
172  sum(ss.cpu3_mw * ss.dur) / sum(ss.dur) AS cpu3_mw,
173  sum(ss.cpu4_mw * ss.dur) / sum(ss.dur) AS cpu4_mw,
174  sum(ss.cpu5_mw * ss.dur) / sum(ss.dur) AS cpu5_mw,
175  sum(ss.cpu6_mw * ss.dur) / sum(ss.dur) AS cpu6_mw,
176  sum(ss.cpu7_mw * ss.dur) / sum(ss.dur) AS cpu7_mw,
177  sum(ss.dsu_scu_mw * ss.dur) / sum(ss.dur) AS dsu_scu_mw
178FROM _interval_intersect_single!($ts, $dur, _ii_subquery!(_system_state_mw)) AS ii
179JOIN _system_state_mw AS ss
180  ON ss._auto_id = id;
181