首页
视频
资源
登录
转
CPU上下文切换(下)
4004
人阅读
2021/7/24 19:17
总访问:
2658620
评论:
0
收藏:
0
手机
分类:
linux
![ubuntu](https://img.tnblog.net/arcimg/hb/d4362a6a18e949a29eea9dcdf50612ed.jpg "ubuntu") >#CPU上下文切换(下) [TOC] 查看系统的上下文切换情况 ------------ >### vmstat工具介绍 tn>`vmstat`是一个常用的系统性能分析工具,主要用来分析系统的内存使用情况,也常用来分析 CPU 上下文切换和中断的次数。 ```bash # 每隔5秒输出1组数据 vmstat 5 ``` ![](https://img.tnblog.net/arcimg/hb/08491dfb74ca490b8c82543616e46a2b.png) >关于结果中每一列的意思: | 列名 | 意义 | | ------------ | ------------ | | `cs` (context switch) | 是每秒上下文切换的次数。 | | `in` (interrupt) | 则是每秒中断的次数。 | | `r` (Running or Runnable) | 是就绪队列的长度,也就是正在运行和等待CPU的进程数。 | | `b`(Blocked) | 则是处于不可中断睡眠的进程数。 | tn>可以看到,这个例子中第一个的上下文切换次数 `cs` 是 1978 次,而系统中断次数 `in` 则是 910 次,而就绪队列长度 `r`是3,不可中断状态进程数 `b` 都是 0。 >### pidstat查看每个进程上下文切换的情况 ```bash # 每隔5秒输出1组数据 pidstat -w 5 ``` ![](https://img.tnblog.net/arcimg/hb/0de59d3de6d34f8a8dd82a8e6193d855.png) >一个是 `cswch` ,表示每秒自愿上下文切换(voluntary context switches)的次数,另一个则是 `nvcswch` ,表示每秒非自愿上下文切换(non voluntary context switches)的次数。 tn>有两个重要的概念:<br/> 1.所谓自愿上下文切换,是指进程无法获取所需要资源,导致的上下文切换。比如说,I/O、内存等系统资源不足时,就会发生自愿上下文切换。<br/> 2.而非自愿上下文切换,则是指进程由于时间片等原因,被系统强制调度,进而发生的上下文切换。比如说,大量进程都在争抢CPU时,就容易发生非自愿上下文切换。 >### sysbech介绍 tn>sysbench 是一个多线程的基准测试工具,一般用来评估不同系统参数下的数据库负载情况。当然,在这次案例中,我们只把它当成一个异常进程来看,作用是模拟上下文切换过多的问题。 (运行时,先安装请使用root用户运行) ```bash # 间隔1秒后输出1组数据 vmstat 1 1 procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 0 0 0 6984064 92668 830896 0 0 2 19 19 35 1 0 99 0 0 ``` >### 案例与分析 <br/> >首先,在第一个终端里运行 sysbench ,模拟系统多线程调度的瓶颈: ```bash # 以10个线程运行5分钟的基准测试,模拟多线程切换的问题 sysbench --threads=10 --max-time=300 threads run ``` >接着,在第二个终端运行 vmstat ,观察上下文切换情况: ```bash # 每隔1秒输出1组数据(需要Ctrl+C才结束) vmstat 1 procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpd free buff cache si so bi bo in cs us sy id wa st 6 0 0 6487428 118240 1292772 0 0 0 0 9019 1398830 16 84 0 0 0 8 0 0 6487428 118240 1292772 0 0 0 0 10191 1392312 16 84 0 0 0 ``` tn>cs 列的上下文切换次数从之前的 35 骤然上升到了 139 万.同时也要观察下面几个指标: - `r` 列:就绪队列的长度已经到了 8,远远超过了系统 CPU 的个数 2,所以肯定会有大量的 CPU 竞争。 - `us`(user)和 `sy`(system)列:这两列的 CPU 使用率加起来上升到了 100%,其中系统 CPU 使用率,也就是 sy 列高达 84%,说明 CPU 主要是被内核占用了。 - `in` 列:中断次数也上升到了 1 万左右,说明中断处理也是个潜在的问题。 >在第三个终端再用 pidstat 来看一下, CPU 和进程上下文切换的情况: ```bash # 每隔1秒输出1组数据(需要 Ctrl+C 才结束) # -w参数表示输出进程切换指标,而-u参数则表示输出CPU使用指标 pidstat -w -u 1 08:06:33 UID PID %usr %system %guest %wait %CPU CPU Command 08:06:34 0 10488 30.00 100.00 0.00 0.00 100.00 0 sysbench 08:06:34 0 26326 0.00 1.00 0.00 0.00 1.00 0 kworker/u4:2 08:06:33 UID PID cswch/s nvcswch/s Command 08:06:34 0 8 11.00 0.00 rcu_sched 08:06:34 0 16 1.00 0.00 ksoftirqd/1 08:06:34 0 471 1.00 0.00 hv_balloon 08:06:34 0 1230 1.00 0.00 iscsid 08:06:34 0 4089 1.00 0.00 kworker/1:5 08:06:34 0 4333 1.00 0.00 kworker/0:3 08:06:34 0 10499 1.00 224.00 pidstat 08:06:34 0 26326 236.00 0.00 kworker/u4:2 08:06:34 1000 26784 223.00 0.00 sshd ``` >从 pidstat 的输出你可以发现,CPU 使用率的升高果然是 sysbench 导致的,它的 CPU 使用率已经达到了 100%。但上下文切换则是来自其他进程,包括非自愿上下文切换频率最高的 pidstat ,以及自愿上下文切换频率最高的内核线程 kworker 和 sshd。<br/> 不过,细心的你肯定也发现了一个怪异的事儿:pidstat 输出的上下文切换次数,加起来也就几百,比 vmstat 的 139 万明显小了太多。这是怎么回事呢?难道是工具本身出了错吗?<br/> 别着急,在怀疑工具之前,我们再来回想一下,前面讲到的几种上下文切换场景。其中有一点提到, Linux 调度的基本单位实际上是线程,而我们的场景 sysbench 模拟的也是线程的调度问题,那么,是不是 pidstat 忽略了线程的数据呢?</br> 通过运行 man pidstat ,你会发现,pidstat 默认显示进程的指标数据,加上 `-t` 参数后,才会输出线程的指标。 所以,我们可以在第三个终端里, Ctrl+C 停止刚才的 pidstat 命令,再加上 -t 参数,重试一下看看: ```bash # 每隔1秒输出一组数据(需要 Ctrl+C 才结束) # -wt 参数表示输出线程的上下文切换指标 pidstat -wt 1 08:14:05 UID TGID TID cswch/s nvcswch/s Command ... 08:14:05 0 10551 - 6.00 0.00 sysbench 08:14:05 0 - 10551 6.00 0.00 |__sysbench 08:14:05 0 - 10552 18911.00 103740.00 |__sysbench 08:14:05 0 - 10553 18915.00 100955.00 |__sysbench 08:14:05 0 - 10554 18827.00 103954.00 |__sysbench ... ``` >在你就能看到了,虽然 sysbench 进程(也就是主线程)的上下文切换次数看起来并不多,但它的子线程的上下文切换次数却有很多。看来,上下文切换罪魁祸首,还是过多的 sysbench 线程。<br/> 我们已经找到了上下文切换次数增多的根源,那是不是到这儿就可以结束了呢?当然不是。不知道你还记不记得,前面在观察系统指标时,除了上下文切换频率骤然升高,还有一个指标也有很大的变化。是的,正是中断次数。中断次数也上升到了 1 万,但到底是什么类型的中断上升了,现在还不清楚。我们接下来继续抽丝剥茧找源头。<br/> 既然是中断,我们都知道,它只发生在内核态,而 pidstat 只是一个进程的性能分析工具,并不提供任何关于中断的详细信息,怎样才能知道中断发生的类型呢?<br/> 没错,那就是从 `/proc/interrupts` 这个只读文件中读取。`/proc` 实际上是 Linux 的一个虚拟文件系统,用于内核空间与用户空间之间的通信。`/proc/interrupts` 就是这种通信机制的一部分,提供了一个只读的中断使用情况。<br/> 我们还是在第三个终端里, Ctrl+C 停止刚才的 pidstat 命令,然后运行下面的命令,观察中断的变化情况: ```bash # -d 参数表示高亮显示变化的区域 watch -d cat /proc/interrupts CPU0 CPU1 ... RES: 2450431 5279697 Rescheduling interrupts ... ``` >观察一段时间,你可以发现,变化速度最快的是重调度中断(RES),这个中断类型表示,唤醒空闲状态的 CPU 来调度新的任务运行。这是多处理器系统(SMP)中,调度器用来分散任务到不同 CPU 的机制,通常也被称为处理器间中断(Inter-Processor Interrupts,IPI)。
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739
👈{{preArticle.title}}
👉{{nextArticle.title}}
评价
{{titleitem}}
{{titleitem}}
{{item.content}}
{{titleitem}}
{{titleitem}}
{{item.content}}
尘叶心繁
这一世以无限游戏为使命!
博主信息
排名
6
文章
6
粉丝
16
评论
8
文章类别
.net后台框架
171篇
linux
17篇
linux中cve
1篇
windows中cve
0篇
资源分享
10篇
Win32
3篇
前端
28篇
传说中的c
4篇
Xamarin
9篇
docker
15篇
容器编排
101篇
grpc
4篇
Go
15篇
yaml模板
1篇
理论
2篇
更多
Sqlserver
4篇
云产品
39篇
git
3篇
Unity
1篇
考证
2篇
RabbitMq
23篇
Harbor
1篇
Ansible
8篇
Jenkins
17篇
Vue
1篇
Ids4
18篇
istio
1篇
架构
2篇
网络
7篇
windbg
4篇
AI
18篇
threejs
2篇
人物
1篇
嵌入式
4篇
python
13篇
HuggingFace
8篇
pytorch
9篇
opencv
6篇
Halcon
5篇
最新文章
最新评价
{{item.articleTitle}}
{{item.blogName}}
:
{{item.content}}
关于我们
ICP备案 :
渝ICP备18016597号-1
网站信息:
2018-2024
TNBLOG.NET
技术交流:
群号656732739
联系我们:
contact@tnblog.net
欢迎加群
欢迎加群交流技术