103 lines
2.8 KiB
Markdown
103 lines
2.8 KiB
Markdown
# Common queries
|
|
|
|
This page acts as a reference guide for queries which often appear when
|
|
performing ad-hoc analysis.
|
|
|
|
## Computing CPU time for slices
|
|
If collecting traces which including scheduling information (i.e. from ftrace)
|
|
as well as userspace slices (i.e. from atrace), the actual time spent running
|
|
on a CPU for each userspace slice can be computed: this is commonly known as
|
|
the "CPU time" for a slice.
|
|
|
|
Firstly, setup the views to simplify subsequent queries:
|
|
```
|
|
DROP VIEW IF EXISTS slice_with_utid;
|
|
CREATE VIEW slice_with_utid AS
|
|
SELECT
|
|
ts,
|
|
dur,
|
|
slice.name as slice_name,
|
|
slice.id as slice_id, utid,
|
|
thread.name as thread_name
|
|
FROM slice
|
|
JOIN thread_track ON thread_track.id = slice.track_id
|
|
JOIN thread USING (utid);
|
|
|
|
DROP TABLE IF EXISTS slice_thread_state_breakdown;
|
|
CREATE VIRTUAL TABLE slice_thread_state_breakdown
|
|
USING SPAN_LEFT_JOIN(
|
|
slice_with_utid PARTITIONED utid,
|
|
thread_state PARTITIONED utid
|
|
);
|
|
```
|
|
|
|
Then, to compute the CPU time for all slices in the trace:
|
|
```
|
|
SELECT slice_id, slice_name, SUM(dur) AS cpu_time
|
|
FROM slice_thread_state_breakdown
|
|
WHERE state = 'Running'
|
|
GROUP BY slice_id;
|
|
```
|
|
|
|
You can also compute CPU time for a specific slice:
|
|
```
|
|
SELECT slice_name, SUM(dur) AS cpu_time
|
|
FROM slice_thread_state_breakdown
|
|
WHERE slice_id = <your slice id> AND state = 'Running';
|
|
```
|
|
|
|
These queries can be varied easily to compute other similar metrics.
|
|
For example to get the time spent "runnable" and in "uninterruptible sleep":
|
|
```
|
|
SELECT
|
|
slice_id,
|
|
slice_name,
|
|
SUM(CASE state = 'R' THEN dur ELSE 0 END) AS runnable_time,
|
|
SUM(CASE state = 'D' THEN dur ELSE 0 END) AS uninterruptible_time
|
|
FROM slice_thread_state_breakdown
|
|
GROUP BY slice_id;
|
|
```
|
|
|
|
## Computing scheduling time by woken threads
|
|
A given thread might cause other threads to wake up i.e. because work was
|
|
scheduled on them. For a given thread, the amount of time threads it
|
|
woke up ran for can be a good proxy to understand how much work is being
|
|
spawned.
|
|
|
|
To compute this, the following query can be used:
|
|
```
|
|
SELECT
|
|
SUM((
|
|
SELECT dur FROM sched
|
|
WHERE
|
|
sched.ts > wakee_runnable.ts AND
|
|
wakee_runnable.utid = wakee_runnable.utid
|
|
ORDER BY ts
|
|
LIMIT 1
|
|
)) AS scheduled_dur
|
|
FROM thread AS waker
|
|
JOIN thread_state AS wakee_runnable ON waker.utid = wakee_runnable.waker_utid
|
|
WHERE waker.name = <your waker thread name here>
|
|
```
|
|
|
|
To do this for all the threads in the trace simultaenously:
|
|
```
|
|
SELECT
|
|
waker_process.name AS process_name,
|
|
waker.name AS thread_name,
|
|
SUM((
|
|
SELECT dur FROM sched
|
|
WHERE
|
|
sched.ts > wakee_runnable.ts AND
|
|
sched.utid = wakee_runnable.utid
|
|
ORDER BY ts
|
|
LIMIT 1
|
|
)) AS scheduled_dur
|
|
FROM thread AS waker
|
|
JOIN process AS waker_process USING (upid)
|
|
JOIN thread_state AS wakee_runnable ON waker.utid = wakee_runnable.waker_utid
|
|
WHERE waker.utid != 0
|
|
GROUP BY 1, 2
|
|
ORDER BY 3 desc
|
|
```
|