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 thread 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_thread_utilization_per_period( 27 -- Length of the period on which utilization should be averaged. 28 interval LONG, 29 -- Utid of the thread. 30 utid JOINID(thread.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_utid AS ( 46 SELECT 47 ts, 48 ts_end, 49 utid 50 FROM sched 51 WHERE 52 utid = $utid 53 ) 54SELECT 55 * 56FROM _cpu_avg_utilization_per_period!($interval, sched_for_utid); 57 58-- Returns a table of thread utilization per second. 59-- Utilization is calculated as sum of average utilization of each CPU in each 60-- period, which is defined as a multiply of |interval|. For this reason 61-- first and last period might have lower then real utilization. 62CREATE PERFETTO FUNCTION cpu_thread_utilization_per_second( 63 -- Utid of the thread. 64 utid JOINID(thread.id) 65) 66RETURNS TABLE ( 67 -- Timestamp of start of a second. 68 ts TIMESTAMP, 69 -- Sum of average utilization over period. 70 -- Note: as the data is normalized, the values will be in the 71 -- [0, 1] range. 72 utilization DOUBLE, 73 -- Sum of average utilization over all CPUs over period. 74 -- Note: as the data is unnormalized, the values will be in the 75 -- [0, cpu_count] range. 76 unnormalized_utilization DOUBLE 77) AS 78SELECT 79 * 80FROM cpu_thread_utilization_per_period(time_from_s(1), $utid); 81 82-- Aggregated CPU statistics for each thread. 83CREATE PERFETTO TABLE cpu_cycles_per_thread ( 84 -- Thread 85 utid JOINID(thread.id), 86 -- Sum of CPU millicycles 87 millicycles LONG, 88 -- Sum of CPU megacycles 89 megacycles LONG, 90 -- Total runtime duration 91 runtime LONG, 92 -- Minimum CPU frequency in kHz 93 min_freq LONG, 94 -- Maximum CPU frequency in kHz 95 max_freq LONG, 96 -- Average CPU frequency in kHz 97 avg_freq LONG 98) AS 99SELECT 100 utid, 101 cast_int!(SUM(dur * freq / 1000)) AS millicycles, 102 cast_int!(SUM(dur * freq / 1000) / 1e9) AS megacycles, 103 sum(dur) AS runtime, 104 min(freq) AS min_freq, 105 max(freq) AS max_freq, 106 cast_int!(SUM((dur * freq / 1000)) / SUM(dur / 1000)) AS avg_freq 107FROM _cpu_freq_per_thread 108GROUP BY 109 utid; 110 111-- Aggregated CPU statistics for each thread in a provided interval. 112CREATE PERFETTO FUNCTION cpu_cycles_per_thread_in_interval( 113 -- Start of the interval. 114 ts TIMESTAMP, 115 -- Duration of the interval. 116 dur LONG 117) 118RETURNS TABLE ( 119 -- Thread with CPU cycles and frequency statistics. 120 utid JOINID(thread.id), 121 -- Sum of CPU millicycles 122 millicycles LONG, 123 -- Sum of CPU megacycles 124 megacycles LONG, 125 -- Total runtime duration 126 runtime LONG, 127 -- Minimum CPU frequency in kHz 128 min_freq LONG, 129 -- Maximum CPU frequency in kHz 130 max_freq LONG, 131 -- Average CPU frequency in kHz 132 avg_freq LONG 133) AS 134SELECT 135 utid, 136 cast_int!(SUM(ii.dur * freq / 1000)) AS millicycles, 137 cast_int!(SUM(ii.dur * freq / 1000 )/ 1e9) AS megacycles, 138 sum(ii.dur) AS runtime, 139 min(freq) AS min_freq, 140 max(freq) AS max_freq, 141 cast_int!(SUM((ii.dur * freq / 1000)) / SUM(ii.dur / 1000)) AS avg_freq 142FROM _interval_intersect_single!($ts, $dur, _cpu_freq_per_thread) AS ii 143JOIN _cpu_freq_per_thread AS c 144 USING (id) 145GROUP BY 146 utid; 147