前言:虽然有翻译软件,虽然有chatgpt,毕竟语言隔阂,对这个工具还是一知半解,因此想通过翻译的方式和大家来一起学习下Perfetto这个强大的工具
#####################以下分割线#####################
英文原文在这里
在Android和Linux上,Perfetto可以通过Linux内核的 ftrace收集调度程序的trace。
这允许获得细粒度的调度事件,例如:
- 在任何时间点,哪个线程在哪个CPU核心上调度,精度为纳秒。
- 正在运行的线程被取消调度的原因(例如,抢占、在互斥对象上被阻塞、阻塞系统调用或任何其他等待队列)
- 线程有资格执行的时间点,即使它没有立即放在任何CPU运行队列中,以及使其可执行的源线程。
UI
UI将各个调度事件表示为切片:
![](https://img.haomeiwen.com/i2972443/7a1d750cb11dda37.png)
单击CPU切片会在详细信息面板中显示相关信息:
![](https://img.haomeiwen.com/i2972443/17fcadec90b148cc.png)
向下滚动,当展开进程时,调度事件还为每个线程创建一个轨道,这允许跟踪单个线程状态的演变:
![](https://img.haomeiwen.com/i2972443/7e620156950d117b.png)
SQL
在SQL级别,调度数据可从sched_slice表中查询。
select ts, dur, cpu, end_state, priority, process.name, thread.name
from sched_slice left join thread using(utid) left join process using(upid)
![](https://img.haomeiwen.com/i2972443/745b003e9a1e20f5.png)
TraceConfig
要收集这些数据,请包括以下数据源:
# Scheduling data from the kernel.
data_sources: {
config {
name: "linux.ftrace"
ftrace_config {
compact_sched: {
enabled: true
}
ftrace_events: "sched/sched_switch"
# optional: precise thread lifetime tracking:
ftrace_events: "sched/sched_process_exit"
ftrace_events: "sched/sched_process_free"
ftrace_events: "task/task_newtask"
ftrace_events: "task/task_rename"
}
}
}
# Adds full process names and thread<>process relationships:
data_sources: {
config {
name: "linux.process_stats"
}
}
调度唤醒和延迟分析
通过在TraceConfig中进一步启用以下功能,ftrace数据源还将记录调度唤醒事件:
ftrace_events: "sched/sched_wakeup_new"
ftrace_events: "sched/sched_waking"
虽然只有当线程处于R(不可运行)状态且在CPU运行队列上运行时才会发出 sched_switch
事件,但当任何事件导致线程状态更改时,都会发出sched_waking事件。
比如以下示例:
Thread A
condition_variable.wait()
Thread B
condition_variable.notify()
当线程A调用wait()挂起时,它将进入状态S(睡眠),并从CPU运行队列中移除。当线程B通知变量condition_variable时,内核会将线程A转换为R(不可运行)状态。此时线程A有资格被放回运行队列中。然而,这可能在一段时间内不会发生,例如:
- 所有CPU可能都忙于运行其他线程,线程A需要等待分配一个运行队列槽(或者其他线程具有更高的优先级)。
- 当前CPU之外的其他一些CPU,但是调度程序负载均衡器可能需要一些时间来移动另一个CPU上的线程。
除非使用实时线程优先级,否则大多数Linux内核调度程序配置都不是严格的工作保护配置。例如,调度器可能更倾向于等待一段时间,希望在当前CPU上运行的其他线程进入空闲状态,从而避免跨CPU迁移,这可能更费时费力(功耗)。
注意:sched_waking和sched_wakeup提供的信息几乎相同。不同之处在于CPU之间的唤醒事件,这些事件涉及处理器间中断。前者在源(唤醒)CPU上发射,后者在目标(唤醒)CPU上发射。sched_waking通常足以进行延迟分析,除非您正在研究由于跨处理器间处理而导致的延迟。
启用sched_weaking事件时,在选择CPU切片时,UI中将显示以下内容:
![](https://img.haomeiwen.com/i2972443/6704e7db3fd428b2.png)
解码end_state
sched_slice 表包含有关系统调度活动的信息:
> select * from sched_slice limit 1
id type ts dur cpu utid end_state priority
0 sched_slice 70730062200 125364. 0 1 S 130
表中的每一行都显示了给定线程(utild)何时开始运行(ts)、在哪个内核上运行(cpu)、运行了多长时间(dur)以及停止运行的原因:end_state。
end_state被编码为一个或多个ascii字符。可以使用以下翻译将end_state转换为可读文本:
![](https://img.haomeiwen.com/i2972443/9f06616c2ea06d7f.png)
但并不是所有的字符组合都有意义。
如果我们不知道调度何时结束(例如,因为trace在线程仍在运行时结束),end_state将为NULL,dur将为-1。
#####################以上分割线#####################
后记:
1 本次主要使用百度翻译,虽然被骂,但至少翻译这个工具降低了门槛。
2 英文文档中的长难句真的是又长又难,基于百度的翻译,然后自己再调整下,水平实在有限。
3 技术背景知识不够,有些专有名词不知道怎么翻译,也不知道百度翻译的是否准确,功夫在诗外。
4 万事开头难,中间难不难,还不知道。中间的事后面再说,正确一天翻译一篇。
5 虽然可能会有人不屑,但总要有人去做不起眼的小事。
6 google 厉害,这个perfetto 工具也很厉害。君子善假于物也。
7 工具的使用是最简单的入门,背后还有更多的东西值得学习。
8 水平实在有限,闻过则喜,希望有更多的人反馈,期待更好的建议
网友评论