那些吃CPU的大户原创
最近沉浸在代码的世界里,处于两耳不闻窗外事的状态。今晚偶有闲暇,看了一眼任务管理器,IDLE进程的时间居然有800多小时,还有多个进程的CPU净时间达到小时级别。
如下图所示,IDLE进程的CPU净时间为832个小时18分15秒。这说明我很长时间没有重启这台电脑了。除了IDLE进程,CPU净时间达到小时级别的还有8位,它们是本文的主角。
8个达到小时级别的进程分别是:
-
系统进程,排名第1位,累计用CPU时间接近17个小时,这个很不正常,稍后深入探究
-
dwm,桌面窗口管理器,排名第2位,也有些意外
-
ism2,英特尔公司的软件更新管理工具,排名第3位,不干什么正事的应用,还花这么多时间,多半是有劣质代码乱跑,不过算了吧,不多说了
-
msmpeng.exe,Windows自带的安全引擎,一般来说,安全软件是吃CPU的大户,一般它是要排在前三的,现在落到第4了,真的算很好了,要表扬一下
-
svchost.exe,后台服务的宿主进程,根据进程号查一下,这个进程里的服务是superfetch,提高性能用的,念其用心良苦,花些时间也不责怪它了
-
baidunetdisk.exe,百度网盘的客户端,也就是以前的百度云管家,老雷曾经批判过的。不知道是不是与老雷的文章有关,文章发表后,这个工具洗心革面,不仅改了以前的问题,而且改了名字。安静一年多了,最近一段时间感觉又有些激进,经常占很多CPU和I/O。可能是团队里来新员工了吧?
-
接下来两位是explorer和powerpoint,没啥好说的了,两个人的活确实比较累
为什么达到小时级别值得关注呢?因为今天的CPU太快了,真可谓风驰电掣,一秒钟可以执行几G条指令。不信你看,任务管理器里面排在后面的很多程序用的CPU净时间都是0小时0分0秒,这些都是绿色标兵。
值得表扬的是旺旺客户端(加亮的那个),老雷今年年初曾经批评过它,开发工程师联系我,说会改正问题,看来改进的不错。
回过头来再说系统进程吧,它是内核的宿主。内核相当于软件世界的ZF,按说它应该比较轻,不花什么资源。但是现在它却占了最多的CPU时间(如此说话时,不包括IDLE进程)。
当内核被普通线程调用时,它所占的时间是记录在调用线程上的。因此, 系统进程占的时间都是它自己的系统线程运行时花费的。
观察任务管理器,系统进程的线程数多达190个。那么,是哪个系统线程花的时间比较多呢?要回答这个问题,没有专业工具不行了。
唤出WinDBG,开始本地内核调试。“啊?老雷,你的机器总启用着内核调试啊?”
“是的!”
执行!process 4列出系统进程的所有线程。WinDBG一边列线程,一边加载符号,花了很久,终于搞定。
然后搜索“KernelTime 0n
” (n为1-9),于是发现一个使用4小时多的线程,有图有真相,且看:
UserTime 00:00:00.000
KernelTime 04:24:43.437
这是干什么的线程呢?
从栈回溯来看,线程的主函数是dxgmms2!VidMmWorkerThreadProc,其中,dxgmms2是模块名,搜索互联网,可以找到很多与这个模块有关的蓝屏崩溃。它还有个同门兄弟,叫dxgmms1,也是一样,有很多崩溃记录。
那么这兄弟两个是谁家的呢?是微软家的。
做什么用的呢?是管理GPU的。再具体一点,它们肩负着两个与GPU相关的重要任务:
-
显存管理,简称VidMM
-
GPU调度,简称VidSchi
从上面线程的工作函数名来看,VidMmWorkerThreadProc,它是属于VidMM的。
继续搜索用时超过2小时的线程,还有如下一个:
看它的工作函数VidSchiWorkerThread,居然就是dxgmms中的调度器线程:
dxgmms2!VidSchiRun_PriorityTable
dxgmms2!VidSchiWorkerThread
继续搜索,还有一个超过2小时的线程,是igfxdcd,它是英特尔的GPU调试辅助驱动,用于调试OpenCL程序。它的设计明显存在缺欠,不管是否在调试,都有一个系统线程在跑,真是不应该。
继续搜索超过1小时的系统线程,有两个,一个是KeBalanceSetManager
,是NT内核自己的,用来修剪进程工作集的。
另一个是ZeroPageThread
,是用来准备清零内存页的,在内核启动时,是这个线程发起关键的执行体初始化动作,内核启动后,它退居二线,专门负责把内存页清0,当驱动程序需要已经清0的内存页时,满足需要。
综上,超过小时级别的系统线程有5个,三个是GPU相关的,另外两个是普通内存相关的。它们加起来一共消耗了10个小时多的CPU净时间,很是惊人。