Linux通过上下文切换(ctxt_switches )判断程序属于IO密集型还是计算密集型

前言

判断一个程序属于IO密集型还是计算密集型有利于后续对程序进行并行优化,尤其是Cpython解释器下的python程序(GIL锁)。本文将先介绍判断方法,再结合一个实际案例进行分析。

上下文切换

上下文切换一般指用户态和内核态间的切换,通常切换的发生是因为用户程序在运行过程中产生了系统调用。在Linux中,上下文切换可分为自愿上下文切换(voluntary_ctxt_switches)和非自愿上下文切换(nonvoluntary_ctxt_switches),自愿上下文切换如字面意思,是一种主动的行为,通常是程序主动地产生了系统调用行为,如IO操作,IO操作越多,自愿上下文切换次数越多。非自愿上下文切换和前者相反,它更多体现为“被切换”、“被中断”,我们知道操作系统会通过相应硬件产生时钟脉冲中断进行进程调度,那么一个程序计算得越久,它被时钟脉冲信号“中断”、被剥夺时间片给其他进程的次数就越多,因此非自愿上下文切换的次数越多,基于此我们就可以初略判断一个程序属于IO密集型还是计算密集型。

在Linux中,进程的上下文切换信息存储在/proc/${PID}/status文件中,${PID}表示当前进程的进程号,因此在目标程序运行结束前开一个子进程去找到有关ctxt_switches的信息就可以分析出当前进程属于IO密集型还是计算密集型。

来验证一下,我服务器搭了个NodeJs服务,FTP用得比较多,一般用来上传下载文件,目前运行了2年多左右,理论上应该属于IO密集型(云服务一般大量时间在监听wait,计算不密集)。NodeJs服务进程为8606,cat一下8606的status文件:

[root@izwz99t7wh8lhysugop73tt ~]# cat /proc/8606/status | grep ctxt
voluntary_ctxt_switches:	151581101
nonvoluntary_ctxt_switches:	42009
[root@izwz99t7wh8lhysugop73tt ~]# 

可见自愿上下文切换数量远大于非自愿上下文切换的数量,因此NodeJS的FTP服务属于IO密集型,验证正确。

实际案例

对方用我写的python程序提取1个T的日志信息,一个程序大概要跑好几天,由于程序中涉及到IO操作,潜意识地认为1个T的IO提取任务应该是IO密集型,所以用多线程模型比较好(python一般IO密集型用多线程,计算密集型用多进程),但为验证直觉还是要进行实际测试。我这边提取程序为extract_new.py,在程序末尾添加两行代码即可:

import os
import subprocess

...

pid = os.getpid()
subprocess.call(['cat /proc/{}/status | grep ctxt'.format(pid)],shell=True)

subprocess表示开启子进程调用shell,voluntary_ctxt_switches和nonvoluntary_ctxt_switches会作为结果在最后输出。依葫芦画瓢,其他语言如java则可选择Runtime类进行实现。

对方一份日志大概近百万行,第一次实验generate几百行的模拟日志测试

[root@izwz99t7wh8lhysugop73tt extract]# python3 extract_new.py 
当前进度:0.685%
...
当前进度:99.315%
当前进度:100.0%
voluntary_ctxt_switches:	32
nonvoluntary_ctxt_switches:	900

发现自愿上下文切换居然要比非自愿少这么多,难道提取程序属于计算密集型?我怀疑是模拟日志的行数太少导致IO未凸显出,于是我将日志行数调到20w行左右再进行测试:

[root@izwz99t7wh8lhysugop73tt extract]# python3 extract_new.py 
当前进度:0.685%
...
当前进度:99.315%
当前进度:100.0%
voluntary_ctxt_switches:	16
nonvoluntary_ctxt_switches:	1120

实验结果显示差距更大了,属于典型计算密集型,个人猜测是因为程序中用到了正则等方法处理数据,虽然IO的数据变多但需计算处理的数据变得更多,从而导致上述结果。至此,我们就可以采用多进程的方式进行python任务并行提取了。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值