今天在我的一个微信群里看到有人提到性能分析中的上下文切换的问题。
一个同学提到了上下文切换有自愿和非自愿两种,我觉得能知道上下文切换分为两种的,已经非常不容易了。
在性能分析过程中,我们会经常用一些手段来判断性能瓶颈证据链的逻辑,这个知识点,其实也是非常常用的手段之一。
那么我今天就上下文切换到底自不自愿来给大家闲聊几句。我不打算用特别专业的术语把你忽悠蒙,所以还是写得口语化一些。
首先,得来说说什么是上下文切换(Context Swith),简单来说就是CPU在干着活呢,被打断了,于是从一个进程或线程切换到另一个进程或线程。当然在切换之前会保存当前正在运行的进程或线程的状态,以备切回来可以接着执行。
那CPU为什么要切换呢?有几种情况:
- CPU不足。至于为什么不足,那情况就多了去了。
- 进程或线程自己需要切换。典型的就是进程或线程自己要等待条件满足或这一段的活干完了,于是把CPU释放了。
针对第1种情况:我们得先知道为什么CPU不足。这里也分为两种情况:
1.1 自己消耗的。
1.2 别人消耗的。
针对1.1的情况,那就解决自身的问题。
针对1.2的情况,那就解决别人的问题。
针对第2种情况:那就必然是要分析自己进程或线程的问题了。
下面我们来看一下在具体的分析逻辑中如何展示。
- 第1.1种情况
我这里用最简单的sleep代码来模拟一下,你随便写一个消耗CPU的代码都可以,代码并不重要。
我们只来说说分析逻辑。先看top。
从top里可以看到CPU被消耗光了,确实也都在用户空间us cpu。进程id是15288。下面我们来看vmstat。
从vmstat上来看,并看不到多大的CS。但是已经可以看到CPU队列高、CPU使用率高了。
再来看一下各线程的上下文切换情况:
从上图可以看到nvcswch/s已经有值了,我这里是每秒刷新一次。也就是说每个线程大概每秒被动切换了50多次。
你有没有觉得,这个值看起来似乎并不大是不是?并且在vmstat中也没看到多高的CS切换呀,因为在CPU空闲时也差不多有2000多的切换呀。(在我这个环境中是这样的数值,在其他环境中,这个值会有变化。)
我们来看下没有压力时的vmstat。
你看,是不是cs也有2800多?
这时就有人有疑问了:哎,哎,哎,你别动!你这里有问题呀!为啥有压力的时候cs比没有压力时还低了呢?
嗯,果然眼尖。为什么会出现这种情况呢。因为现在CPU都被15288抢占,本来操作系统正常的CS都抢不到CPU了,只被15288里面的几个进程消耗掉了。那正常的CS就连CPU都抢不到,当然CS也就减少了,这时整个系统其实是处在瘫痪的状态的。
眼尖的同学,应该可以看到,其实中断高了。因为我们这篇文章就讲CS,中断暂时不关联分析,以免让你更晕。