CPU上下文切换分析

摘要:
非自愿上下文切换:则是指进程由于时间片已到等原因,被系统强制调度,进而发生的上下文切换。比如说,大量进程都在争抢CPU时,就容易发生非自愿上下文切换。

一、CPU上下文切换

1、上下文切换,有时也称做进程切换或任务切换,是指CPU从一个进程或线程切换到另一个进程或线程。

2、vmstat是一个常用的系统性能分析工具,主要用来分析系统内存使用情况,也常用来分析CPU上下文切换和中断的次数。

例:vmstat -w

CPU上下文切换分析第1张

上下文切换需要特别关注的四列内容:

cs(context switch)  是每秒上下文切换的次数。
in(interrupt)  则是每秒中断的次数。
r(Running or Runnable)  是就绪队列的长度。
b(Blocked)  则是处于不可中断睡眠状态的进程数。

这个例子中的上下文切换次数 cs 是 12 次,系统中断次数in则是93次,而就绪队列长度 r 和不可中断状态进程数 b 都是 0。

3、vmstat只给出了系统总体的上下文切换情况,如果要看每个进程的详细情况,就需要pidstat了,加上-w选项

例:pidstat -w 2

CPU上下文切换分析第2张

需关注:cswch ,表示每秒自愿上下文切换(voluntary context switches)的次数

nvcswch ,表示每秒非自愿上下文切换(non voluntary context switches)的次数。

自愿上下文切换:是指进程无法获取所需资源,导致的上下文切换。比如说, I/O、内存等系统资源不足时,就会发生自愿上下文切换。

非自愿上下文切换:则是指进程由于时间片已到等原因,被系统强制调度,进而发生的上下文切换。比如说,大量进程都在争抢 CPU 时,就容易发生非自愿上下文切换。

二、使用sysbench 来模拟系统多线程调度切换的情况

1、预先安装 sysbenchsysstat

2、解压tar xvf sysbench-0.4.12.14.tar.gz

3、进入解压目录并执行 ./configure

4、make && make install

5、在第一个终端执行 sysbench --num-threads=10 --max-time=300 --max-requests=10000000 --test=threads run

CPU上下文切换分析第3张

6、在第二个终端运行vmstat观察上下文切换情况:

vmstat -w 1 3

CPU上下文切换分析第4张

可以发现,上下文切换cs已经上升到了256万,同时:

r 列:就绪队列的长度已经到了 9,远远超过了系统 CPU 的个数 2,所以肯定会有大量的 CPU 竞争。

us(user)和 sy(system)列:这两列的 CPU 使用率加起来上升到了 100%,其中系统 CPU 使用率,也就是 sy 列高达 89%,说明 CPU 主要是被内核占用了。

in 列:中断次数也上升到了 3000左右。

综合这几个指标,我们可以知道,系统的就绪队列过长,也就是正在运行和等待 CPU 的进程数过多,导致了大量的上下文切换,而上下文切换又导致了系统 CPU 的占用率升高。

7、使用pidstat查看CPU和进程上下文切换情况:

pidstat -wt -u 1 3   # -wt 参数表示输出线程指标,而 -u 参数则表示输出 CPU 使用指标

CPU上下文切换分析第5张

从 pidstat 的输出你可以发现,CPU 使用率的升高果然是 sysbench 导致的,它的 CPU 使用率已经达到了 194%,虽然 sysbench 进程(也就是主线程)的上下文切换次数看起来很少,但是它的子线程的上下文切换次数却有很多。看来,上下文切换罪魁祸首,还是过多的 sysbench 线程。

8、继续查看中断次数的详细信息

执行:watch -d cat /proc/interrupts  # -d表示高亮显示变化的参数

CPU上下文切换分析第6张

观察一段时间,可以发现变化最快的是重新调度中断(RES),这个中断类型表示,唤醒空闲状态的 CPU 来调度新的任务运行。这是多处理器系统(SMP)中,调度器用来分散任务到不同 CPU 的机制,通常也被称为处理器中断。

总结:

每秒上下文切换多少次算正常?

这个数值主要取决于系统CPU的性能,如果上下文切换比较稳定,那在1万以下都算是正常,如果超过1万或者切换次数出现很大的增长,就很可能出现了性能问题。

cswch ,自愿上下文切换的次数增多了,说明系统正在等待资源,有可能发生了I/O等其它问题;

nvcswch ,非自愿上下文切换的次数增多了,说明进程都在强制调度,也就是在争抢CPU,说明CPU性能成了瓶颈;

in,中断次数增多了,说明CPU被中断,通过分析/proc/interrupt文件来确认中断类型。

免责声明:文章转载自《CPU上下文切换分析》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇java正则表达式Pattern和Matcher在ServiceModel客户端配置中找不到应用协定的默认终结点元素。下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Delphi线程的终止

当线程对象的Execute()执行完毕,我们就认为此线程终止了。这时候,它会调用Delphi的一个标准例程EndThread(),这个例程再调用API函数ExitThread()。由ExitThread()来清除线程所占用的栈。 当结束使用TThread对象时,应该确保已经把这个Delphi对象从内存中清除了。这才能确保所有内存占有都释放掉。尽管在进程终止...

【JVM】CPU飙升问题

前言  线上程序突然CPU飙升,,,在一个并发不大的网站,这种情况基本上99.99%都是程序有死循环。接下来看看怎么具体定位排查吧。 硬啃 看看最近的代码,搜索关键字while,根据我多年临床经验,100%是哪位菜鸟写了bug。 如果找不到原因,继续往下看。 线程dump 1、找出java的进程id jps -l 2、通过进程id找到进程中各个线程的情况...

java如何避免死锁

在有些情况下死锁是可以避免的。本文将展示三种用于避免死锁的技术: 加锁顺序 加锁时限 死锁检测 加锁顺序 当多个线程需要相同的一些锁,但是按照不同的顺序加锁,死锁就很容易发生。 如果能确保所有的线程都是按照相同的顺序获得锁,那么死锁就不会发生。看下面这个例子: Thread 1: lock A lock B Thread 2: wai...

Java任务调度

四种任务调度的 Java 实现: Timer ScheduledExecutor 开源工具包 Quartz 开源工具包 JCronTab Timer 相信大家都已经非常熟悉 java.util.Timer 了,它是最简单的一种实现任务调度的方法,下面给出一个具体的例子: 清单 1. 使用 Timer 进行任务调度 package com.ibm.s...

【转】dbx用法讲解

http://blog.chinaunix.net/uid-25544300-id-328735.html dbx 命令 用途 提供了一个调试和运行程序的环境。 语法 dbx [ -a ProcessID ] [ -c CommandFile ] [ -d NestingDepth ] [ -I Directory ] [ -E DebugEnvironm...

多线程编程5种方法实现线程同步

1:用Interlocked系列函数实现线程同步; 2:用CRITICAL_SECTION及其系列函数实现线程同步; 3:用RTL_SRWLOCK及其系列函数实现线程同步; 4:用事件内核对象实现线程同步; 5:用信号量内核对象实现线程同步;   1:用Interlocked系列函数实现线程同步实例如下: //旋转锁 #include <iostre...