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 linux.cpu.utilization.general; 17 18INCLUDE PERFETTO MODULE time.conversion; 19 20INCLUDE PERFETTO MODULE intervals.intersect; 21 22-- The purpose of this module is to provide high level aggregates of system 23-- utilization, akin to /proc/stat results. 24 25-- Returns a table of system utilization per given period. 26-- Utilization is calculated as sum of average utilization of each CPU in each 27-- period, which is defined as a multiply of |interval|. For this reason 28-- first and last period might have lower then real utilization. 29CREATE PERFETTO FUNCTION cpu_utilization_per_period( 30 -- Length of the period on which utilization should be averaged. 31 interval LONG 32) 33RETURNS TABLE ( 34 -- Timestamp of start of a second. 35 ts TIMESTAMP, 36 -- Sum of average utilization over period. 37 -- Note: as the data is normalized, the values will be in the 38 -- [0, 1] range. 39 utilization DOUBLE, 40 -- Sum of average utilization over all CPUs over period. 41 -- Note: as the data is unnormalized, the values will be in the 42 -- [0, cpu_count] range. 43 unnormalized_utilization DOUBLE 44) AS 45SELECT 46 * 47FROM _cpu_avg_utilization_per_period!( 48 $interval, 49 (SELECT * FROM sched WHERE NOT utid IN 50 ( 51 SELECT utid FROM thread WHERE is_idle 52 ) 53 ) 54); 55 56-- Table with system utilization per second. 57-- Utilization is calculated by sum of average utilization of each CPU every 58-- second. For this reason first and last second might have lower then real 59-- utilization. 60CREATE PERFETTO TABLE cpu_utilization_per_second ( 61 -- Timestamp of start of a second. 62 ts TIMESTAMP, 63 -- Sum of average utilization over period. 64 -- Note: as the data is normalized, the values will be in the 65 -- [0, 1] range. 66 utilization DOUBLE, 67 -- Sum of average utilization over all CPUs over period. 68 -- Note: as the data is unnormalized, the values will be in the 69 -- [0, cpu_count] range. 70 unnormalized_utilization DOUBLE 71) AS 72SELECT 73 ts, 74 utilization, 75 unnormalized_utilization 76FROM cpu_utilization_per_period(time_from_s(1)); 77 78-- Aggregated CPU statistics for whole trace. Results in only one row. 79CREATE PERFETTO TABLE cpu_cycles ( 80 -- Sum of CPU millicycles. 81 millicycles LONG, 82 -- Sum of CPU megacycles. 83 megacycles LONG, 84 -- Total runtime of all threads running on all CPUs. 85 runtime LONG, 86 -- Minimum CPU frequency in kHz. 87 min_freq LONG, 88 -- Maximum CPU frequency in kHz. 89 max_freq LONG, 90 -- Average CPU frequency in kHz. 91 avg_freq LONG 92) AS 93SELECT 94 cast_int!(SUM(dur * freq / 1000)) AS millicycles, 95 cast_int!(SUM(dur * freq / 1000) / 1e9) AS megacycles, 96 sum(dur) AS runtime, 97 min(freq) AS min_freq, 98 max(freq) AS max_freq, 99 cast_int!(SUM((dur * freq / 1000)) / SUM(dur / 1000)) AS avg_freq 100FROM _cpu_freq_per_thread; 101 102-- Aggregated CPU statistics in a provided interval. Results in one row. 103CREATE PERFETTO FUNCTION cpu_cycles_in_interval( 104 -- Start of the interval. 105 ts TIMESTAMP, 106 -- Duration of the interval. 107 dur LONG 108) 109RETURNS TABLE ( 110 -- Sum of CPU millicycles. 111 millicycles LONG, 112 -- Sum of CPU megacycles. 113 megacycles LONG, 114 -- Total runtime of all threads running on all CPUs. 115 runtime LONG, 116 -- Minimum CPU frequency in kHz. 117 min_freq LONG, 118 -- Maximum CPU frequency in kHz. 119 max_freq LONG, 120 -- Average CPU frequency in kHz. 121 avg_freq LONG 122) AS 123SELECT 124 cast_int!(SUM(ii.dur * freq / 1000)) AS millicycles, 125 cast_int!(SUM(ii.dur * freq / 1000) / 1e9) AS megacycles, 126 sum(ii.dur) AS runtime, 127 min(freq) AS min_freq, 128 max(freq) AS max_freq, 129 cast_int!(SUM((ii.dur * freq / 1000)) / SUM(ii.dur / 1000)) AS avg_freq 130FROM _interval_intersect_single!($ts, $dur, _cpu_freq_per_thread) AS ii 131JOIN _cpu_freq_per_thread 132 USING (id); 133 134-- Aggregated CPU statistics for each CPU. 135CREATE PERFETTO TABLE cpu_cycles_per_cpu ( 136 -- Unique CPU id. Joinable with `cpu.id`. 137 ucpu LONG, 138 -- The number of the CPU. Might not be the same as ucpu in multi machine cases. 139 cpu LONG, 140 -- Sum of CPU millicycles. 141 millicycles LONG, 142 -- Sum of CPU megacycles. 143 megacycles LONG, 144 -- Total runtime of all threads running on CPU. 145 runtime LONG, 146 -- Minimum CPU frequency in kHz. 147 min_freq LONG, 148 -- Maximum CPU frequency in kHz. 149 max_freq LONG, 150 -- Average CPU frequency in kHz. 151 avg_freq LONG 152) AS 153SELECT 154 ucpu, 155 cpu, 156 cast_int!(SUM(dur * freq / 1000)) AS millicycles, 157 cast_int!(SUM(dur * freq / 1000) / 1e9) AS megacycles, 158 sum(dur) AS runtime, 159 min(freq) AS min_freq, 160 max(freq) AS max_freq, 161 cast_int!(SUM((dur * freq / 1000)) / SUM(dur / 1000)) AS avg_freq 162FROM _cpu_freq_per_thread 163GROUP BY 164 ucpu; 165 166-- Aggregated CPU statistics for each CPU in a provided interval. 167CREATE PERFETTO FUNCTION cpu_cycles_per_cpu_in_interval( 168 -- Start of the interval. 169 ts TIMESTAMP, 170 -- Duration of the interval. 171 dur LONG 172) 173RETURNS TABLE ( 174 -- Unique CPU id. Joinable with `cpu.id`. 175 ucpu LONG, 176 -- CPU number. 177 cpu LONG, 178 -- Sum of CPU millicycles. 179 millicycles LONG, 180 -- Sum of CPU megacycles. 181 megacycles LONG, 182 -- Total runtime of all threads running on CPU. 183 runtime LONG, 184 -- Minimum CPU frequency in kHz. 185 min_freq LONG, 186 -- Maximum CPU frequency in kHz. 187 max_freq LONG, 188 -- Average CPU frequency in kHz. 189 avg_freq LONG 190) AS 191SELECT 192 ucpu, 193 cpu, 194 cast_int!(SUM(ii.dur * freq / 1000)) AS millicycles, 195 cast_int!(SUM(ii.dur * freq / 1000) / 1e9) AS megacycles, 196 sum(ii.dur) AS runtime, 197 min(freq) AS min_freq, 198 max(freq) AS max_freq, 199 cast_int!(SUM((ii.dur * freq / 1000)) / SUM(ii.dur / 1000)) AS avg_freq 200FROM _interval_intersect_single!($ts, $dur, _cpu_freq_per_thread) AS ii 201JOIN _cpu_freq_per_thread 202 USING (id) 203GROUP BY 204 ucpu; 205