一、从一个问题说起

  相信很多人在玩手机还是PC时,都曾碰到过这样一种情况,安装的软件多了系统性能就变慢了,但是去查看CPU利用率一直都低于10%,内存也很充足。我在近期的开发工作中就碰到了类似的情况,不同的是,系统此时只有一个测试程序和几个睡眠的后台进程,说明是系统,特别是驱动部分可能出现问题导致的。 从操作系统角度上分析,以下是一些比较可能的原因:

  1. 大量的中断
    可能是在不断磁盘读写,网络通讯, 也可能是模块使用不当或者硬件上出问题导致外设不断给CPU送中断;
  2. 系统负载高(注意:不是CPU利用率)
    负载高表示有很多程序等待调度运行,它会导致上下文切换频繁。
  3. 上下文切换过于频繁
    上下文切换是指CPU从一个进程切换到另一个进程,这个过程也是需要消耗一定时间的。如果说上下文切换过于频繁,说明CPU用于执行进程代码的时间少了。第2点有提到负载高会引起上下文切换频繁,但是上下文切换频繁负载不一定就高。

  在以往的排查经验中,系统性能下降主要由1引起的,在影响系统性能上表现得比较明显;而2,3则比较隐蔽,即使数值已经异常,只要应用对实时性要求不高,最多就是响应稍慢一些,看不出有什么不妥。因此,底层驱动开发人员一般不会去考虑2,3两点,更别说将它作为评价系统性能的测试指标。刚好我要测试的模块对实时性要求很高,而由于系统在空闲时的上下文切换已经很频繁,测试结果自然不佳。

二、怎么确认上下文切换频繁?

  要解决空闲时上下文切换频繁的问题,首先要了解下多频繁才不正常。/proc/stat文件包含了CPU的活动信息,上下文切换就是其中一项,下面命令输出的粗体大号字体所示,以ctxt开头,它表示系统开机到目前为止的上下文切换总数。

 ~ # cat /proc/stat
cpu
cpu0
intr
ctxt

btime
processes
procs_running
procs_blocked
softirq

  对于分析问题而言,我们更关心每秒钟的上下文切换次数,可通过以下命令计算。

 $cat /proc/stat | grep ctxt && sleep  && cat /proc/stat | grep ctxt
ctxt
ctxt

  每秒上下文切换次数=两者差值/30。针对本例,每秒有237次切换,对于一个空闲的系统,这是相当不正常的。正常数值范围一般不超过50次/秒。不过这也不是固定的,需要根据不同的系统环境决定,比如本人在嵌入式开发主要从事开发POS产品,它与作为服务器的Linux系统相比,实际运行的服务会少很多,上下文切换自然应该更少。另外,如果要求更高的实时性,则数值范围还应进一步缩小,本人分析的产品所定的数值范围就要求空闲时不超过30次/秒。 上面介绍的方法在所有Linux产品上都能支持,如果系统带 vmstat ,通过vmstat查看是一个更便捷的方法。测试结果如下图红色方框所示。

三、上下文切换频繁时怎么排查?

  仅靠总的上下文切换次数无法定位到哪个进程或者哪个驱动出的问题,这时就需要pidstat(在sysstat包里)可以查看具体到每个进程每秒的上下文切换次数,下图是执行 $pidstat -w 1的结果。

  在继续分析上图之前我们先谈一个概念:CPU密集型的进程和IO密集型的进程。CPU密集型的进程时间片总是不够用,CPU使用率必然升高,不需要查看上下文切换;而IO密集型的进程,会被频繁调度,但是每次只处理一小会,从CPU使用率是看不出异常的,这时就需要查看上下文切换。一般来讲IO密集型的进程(内核线程或用户进程)主要是处理读写磁盘,或者网络进来的数据;但是也可能有的进程没有任何IO交互但是表现得像IO密集型进程,比如使用如下方式:

  1. 创建一个内核线程,一启动就睡眠;然后创建一个10MS的timer,每次都去唤醒这个内核线程。
  2. 创建一个用户进程,通过系统调用陷入内核就睡眠,然后创建一个10MS的timer,每次都去唤醒这个进程。

当然,我们不会傻到直接干这样的事,但却可能在无意中间接做了这样的事情,特别是对第1条,比如

  1. 创建一个工作队列,创建一个10MS的timer,每次去schedule_work。

  工作队列也是由一个内核线程在管理,导致的结果就是该内核线程上下文切换将变得极为频繁。 对于上下文切换频繁的进程,我们的关注点就是确认它们是否是IO密集型的,以及在当前系统状态下是否应该表现得像IO密集型进程。 比如一个处理网络数据的进程,如果在没有数据的情况下,也表现得像IO密集型,有很高的切换上下文动作,可能这个进程或者该进程打开的设备驱动设计得不合理。

  有两个内核线程kswapd和events(新内核改为kworker),在特定情况下会表现得像IO密集型进程。其中kswapd是用于管理虚拟内存的,当物理内存不足,需要频繁交换虚拟内存,kswapd的上下文切换将明显增多;而events用来处理工作队列,当不断有work进入排队且这些work处理时间很短时,events的上下文切换会明显增多,对于这种情况,需要分析具体是由哪个驱动引起的。

  回到pidstat的输出,可以看到events/0的上下文切换很高,既然没有什么进程会导致该结果,就只可能是某个驱动文件(ko)在不断地排队work。目前我没有找到比较高效的方法可以迅速定位到每个ko文件对work的使用情况,只能通过lsmod打出已经加载的驱动,并跟以前的系统版本对比哪些做了修改以做对比。最终定位出确实存在某个驱动创建一个10MS的timer,并且每次都schedule_work。在对该驱动优化后,再次输入pidstat -w 1测试,可以看到所有进程的下下文切换都降得很低了。

四、附录

1、交叉编译sysstat 一般的板子都不会带pidstat,需要自己下载sysstat的包编译。好在sysstat直接使用工具链就能编译。操作步骤: 进入源码目录

 $mkdir output
$export SA_DIR=`pwd`/output/var/log/sa
$export conf_dir=`pwd`/output/etc/kksysconfig
$./configure --prefix=`pwd`/output --host=arm-none-linux-gnueabi --disable-man-group
$make
$make install

将output下的bin和lib拷到板子即可。注意交叉编译时要在configure时指名工具链名称,如果你的工具链是arm-none-linux-gnueabi-gcc,那么就传递参数--host=arm-none-linux-gnueabi,如果是arm-eabi-gcc,那么就传递参数--host=arm-eabi,按此规则修改。

2.参考文献

Linux的各种统计信息

CPU-上下文切换,运行队列和使用率

进程上下文切换-残酷的性能杀手(上)

使用pidstat查看Context Switch上下文切换

[嵌入式开发]Linux性能分析——上下文切换的更多相关文章

  1. Linux 性能分析工具汇总合集

    出于对Linux操作系统的兴趣,以及对底层知识的强烈欲望,因此整理了这篇文章.本文也可以作为检验基础知识的指标,另外文章涵盖了一个系统的方方面面.如果没有完善的计算机系统知识,网络知识和操作系统知识, ...

  2. [转]Linux性能分析工具汇总合集

    出于对Linux操作系统的兴趣,以及对底层知识的强烈欲望,因此整理了这篇文章.本文也可以作为检验基础知识的指标,另外文章涵盖了一个系统的方方面面.如果没有完善的计算机系统知识,网络知识和操作系统知识, ...

  3. 超全整理!Linux性能分析工具汇总合集

    转自:http://rdc.hundsun.com/portal/article/731.html?ref=myread 出于对Linux操作系统的兴趣,以及对底层知识的强烈欲望,因此整理了这篇文章. ...

  4. (转)超全整理!Linux性能分析工具汇总合集

    超全整理!Linux性能分析工具汇总合集 原文:http://rdc.hundsun.com/portal/article/731.html 出于对Linux操作系统的兴趣,以及对底层知识的强烈欲望, ...

  5. Linux性能分析命令工具汇总

    转自:http://rdc.hundsun.com/portal/article/731.html?ref=myread 出于对Linux操作系统的兴趣,以及对底层知识的强烈欲望,因此整理了这篇文章. ...

  6. Linux 性能分析 工具命令

    背景知识:具备背景知识是分析性能问题时需要了解的.比如硬件 cache:再比如操作系统内核.应用程序的行为细节往往是和这些东西互相牵扯的,这些底层的东西会以意想不到的方式影响应用程序的性能,比如某些程 ...

  7. 【转】一文掌握 Linux 性能分析之网络篇(续)

    [转]一文掌握 Linux 性能分析之网络篇(续) 在上篇网络篇中,我们已经介绍了几个 Linux 网络方向的性能分析工具,本文再补充几个.总结下来,余下的工具包括但不限于以下几个: sar:统计信息 ...

  8. 【转】一文掌握 Linux 性能分析之网络篇

    [转]一文掌握 Linux 性能分析之网络篇 比较宽泛地讲,网络方向的性能分析既包括主机测的网络配置查看.监控,又包括网络链路上的包转发时延.吞吐量.带宽等指标分析.包括但不限于以下分析工具: pin ...

  9. 【转】一文掌握 Linux 性能分析之 I/O 篇

    [转]一文掌握 Linux 性能分析之 I/O 篇 这是 Linux 性能分析系列的第三篇,前两篇分别讲了 CPU 和 内存,本篇来看 IO. IO 和 存储密切相关,存储可以概括为磁盘,内存,缓存, ...

随机推荐

  1. 一步一步开发Game服务器(二)登陆2

    上一篇文章,讲解了简单的登陆情况.接下来我们继续讲解登陆模块. 在正常的游戏服务器情况下.在尚未登录前可以查看服务器大区情况,登陆后也可以查看服务器大区情况,然后选择大区服务器.进行登录操作. 这样的 ...

  2. SQL Server 2014里的性能提升

    在这篇文章里我想小结下SQL Server 2014引入各种惊艳性能提升!! 缓存池扩展(Buffer Pool Extensions) 缓存池扩展的想法非常简单:把页文件存储在非常快的存储上,例如S ...

  3. CSS3魔法堂:说说Multi-column Layout

    前言  是否记得<读者文摘>中那一篇篇优美感人的文章呢?那除了文章内容外,还记得那报刊.杂志独有的多栏布局吗?  当我们希望将报刊.杂志中的阅读体验迁移到网页上时,最简单直接的方式就是采用 ...

  4. .NET Task揭秘(一)

    Task为.NET提供了基于任务的异步模式,它不是线程,它运行在线程池的线程上.本着开源的精神, 本文以解读基于.NET4.5 Task源码的方式来揭秘Task的实现原理.   Task的创建 Tas ...

  5. canvas孙悟空脚踩白云今年是猴年

    效果查看:http://hovertree.com/texiao/html5/30/ 使用HTML5的canvas画的孙悟空,CSS3画的白云飘飘. 刚擒住了几个妖 又降住了几个魔 魑魅魍魉怎么他就这 ...

  6. jquery删除添加输入文本框

    效果体验:http://hovertree.com/texiao/jquery/67/ 效果图: 参考:http://hovertree.com/h/bjaf/traversing_each.htm ...

  7. Redis 详解 (一) StackExchange.Redis Client

    这期我们来看StackExchange.Redis,这是redis 的.net客户端之一.Redis是一个开源的内存数据存储,可以用来做数据库,缓存或者消息代理服务.目前有不少人在使用ServiceS ...

  8. 在 Visual Studio 等编辑器/IDE中自动切换输入法,不需要手动的有没有?

    使用Visual Studio写代码,经常遇到的一个问题就是切换中文输入法麻烦,输入完注释//,要切换到中文,输入完引号,要输入中文,然后还需要切换回来,有没有? 有时候中文输入法忽然失效有没有?明明 ...

  9. 纯HTML+CSS带说明的黄色导航菜单

    HoverTree带说明的CSS菜单:纯HTML+CSS结构链接带说明的黄色导航 在线体验效果:http://hovertree.com/texiao/css/1.htm 代码如下,保存到HTML文件 ...

  10. Source Map调试压缩后代码

    在前端开发过程中,无论是样式还是脚本,运行时的文件可能是压缩后的,那这个时候调试起来就很麻烦. 这个时候,可以使用Source Map文件来优化调试,Source Map是一个信息文件,里面储存着原代 ...