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-- Returns a table of process utilization per given period. 23-- Utilization is calculated as sum of average utilization of each CPU in each 24-- period, which is defined as a multiply of |interval|. For this reason 25-- first and last period might have lower then real utilization. 26CREATE PERFETTO FUNCTION cpu_process_utilization_per_period( 27 -- Length of the period on which utilization should be averaged. 28 interval LONG, 29 -- Upid of the process. 30 upid JOINID(process.id) 31) 32RETURNS TABLE ( 33 -- Timestamp of start of a second. 34 ts TIMESTAMP, 35 -- Sum of average utilization over period. 36 -- Note: as the data is normalized, the values will be in the 37 -- [0, 1] range. 38 utilization DOUBLE, 39 -- Sum of average utilization over all CPUs over period. 40 -- Note: as the data is unnormalized, the values will be in the 41 -- [0, cpu_count] range. 42 unnormalized_utilization DOUBLE 43) AS 44WITH 45 sched_for_upid AS ( 46 SELECT 47 ts, 48 ts_end, 49 utid 50 FROM sched 51 JOIN thread 52 USING (utid) 53 JOIN process 54 USING (upid) 55 WHERE 56 upid = $upid AND NOT is_idle 57 ) 58SELECT 59 * 60FROM _cpu_avg_utilization_per_period!($interval, sched_for_upid); 61 62-- Returns a table of process utilization per second. 63-- Utilization is calculated as sum of average utilization of each CPU in each 64-- period, which is defined as a multiply of |interval|. For this reason 65-- first and last period might have lower then real utilization. 66CREATE PERFETTO FUNCTION cpu_process_utilization_per_second( 67 -- Upid of the process. 68 upid JOINID(process.id) 69) 70RETURNS TABLE ( 71 -- Timestamp of start of a second. 72 ts TIMESTAMP, 73 -- Sum of average utilization over period. 74 -- Note: as the data is normalized, the values will be in the 75 -- [0, 1] range. 76 utilization DOUBLE, 77 -- Sum of average utilization over all CPUs over period. 78 -- Note: as the data is unnormalized, the values will be in the 79 -- [0, cpu_count] range. 80 unnormalized_utilization DOUBLE 81) AS 82SELECT 83 * 84FROM cpu_process_utilization_per_period(time_from_s(1), $upid); 85 86-- Aggregated CPU statistics for each process. 87CREATE PERFETTO TABLE cpu_cycles_per_process ( 88 -- Unique process id 89 upid JOINID(process.id), 90 -- Sum of CPU millicycles 91 millicycles LONG, 92 -- Sum of CPU megacycles 93 megacycles LONG, 94 -- Total runtime duration 95 runtime LONG, 96 -- Minimum CPU frequency in kHz 97 min_freq LONG, 98 -- Maximum CPU frequency in kHz 99 max_freq LONG, 100 -- Average CPU frequency in kHz 101 avg_freq LONG 102) AS 103SELECT 104 upid, 105 cast_int!(SUM(dur * freq / 1000)) AS millicycles, 106 cast_int!(SUM(dur * freq / 1000) / 1e9) AS megacycles, 107 sum(dur) AS runtime, 108 min(freq) AS min_freq, 109 max(freq) AS max_freq, 110 cast_int!(SUM((dur * freq / 1000)) / SUM(dur / 1000)) AS avg_freq 111FROM _cpu_freq_per_thread 112JOIN thread 113 USING (utid) 114WHERE 115 upid IS NOT NULL 116GROUP BY 117 upid; 118 119-- Aggregated CPU statistics for each process in a provided interval. 120CREATE PERFETTO FUNCTION cpu_cycles_per_process_in_interval( 121 -- Start of the interval. 122 ts TIMESTAMP, 123 -- Duration of the interval. 124 dur LONG 125) 126RETURNS TABLE ( 127 -- Unique process id. 128 upid JOINID(process.id), 129 -- Sum of CPU millicycles 130 millicycles LONG, 131 -- Sum of CPU megacycles 132 megacycles LONG, 133 -- Total runtime duration 134 runtime LONG, 135 -- Minimum CPU frequency in kHz 136 min_freq LONG, 137 -- Maximum CPU frequency in kHz 138 max_freq LONG, 139 -- Average CPU frequency in kHz 140 avg_freq LONG 141) AS 142WITH 143 threads_counters AS ( 144 SELECT 145 c.id, 146 c.ts, 147 c.dur, 148 c.freq, 149 upid 150 FROM _cpu_freq_per_thread AS c 151 JOIN thread 152 USING (utid) 153 ) 154SELECT 155 upid, 156 cast_int!(SUM(ii.dur * freq / 1000)) AS millicycles, 157 cast_int!(SUM(ii.dur * freq / 1000) / 1e9) AS megacycles, 158 sum(ii.dur) AS runtime, 159 min(freq) AS min_freq, 160 max(freq) AS max_freq, 161 cast_int!(SUM((ii.dur * freq / 1000)) / SUM(ii.dur / 1000)) AS avg_freq 162FROM _interval_intersect_single!($ts, $dur, threads_counters) AS ii 163JOIN threads_counters 164 USING (id) 165GROUP BY 166 upid; 167