手记

如何设计CPU密集型与I/O密集型程序

CPU密集型(CPU-Bound)是指系统指花费相对大部分时间在做CPU运算、逻辑判断等,CPU使用率很高,典型的如加密运算;I/O密集型(I/O-Bound)是指系统花费大部分时间在等待相对较慢的I/O操作完成,如硬盘文件的读写。
进程一般赋予I/O密集型的线程优先级高于CPU密集型的线程,通俗点可以想成人机交互的需要有高的响应优先级。实际上这样设置优先级是因为I/O密集型操作通常是要花费一定时间,在此段时间里可以释放对CPU的占用,让CPU去处理CPU密集型的运行,当I/O再次需求CPU参与时又能够获取到CPU的使用权。
前阵子遇到了一个小编程比赛题目,其中有个简答题,一系列的三个小题目,具体题目如下:
问题一:一台主机,单核CPU,只有一块硬盘。现在硬盘上有4个大小为1G的文件,一个程序要将这4个文件读取出来,然后对文件内容进行加密(加密算法是现成的,加密后的数据量和加密前相等),再通过网络发送到服务器上。设单个文件最大读取速度为 2MB/S,单个线程对文件进行加密的速度为1MB/S(加密算法支持多线程协同并行处理), 网络最大传输带宽为 8MB/S。请你给出最优的设计方案。
 问题二:现在将主机配置升级,改为8核CPU, 4块硬盘4个大小为1G的文件,分别存放在4块硬盘上,一个程序要将这4个文件读取出来,然后对文件内容进行加密(加密算法是现成的,加密后的数据量和加密前相等),再通过网络发送到服务器上。设单个文件读取速度为 2MB/S,单个线程对文件进行加密的速度为1MB/S(加密算法支持多线程协同并行处理),网络最大传输带宽为 8MB/S。请你给出最优的设计方案。
问题三:基于题目二。在8核CPU的主机上现在额外运行了一些关键程序,要求我们设计的程序CPU占用率不能超过 25%,给出你的设计方案。 

有兴趣的童鞋可以先思考下,或者直接跳过分割线。




既然作为一个考题,必然有其考的知识点。个人觉得本题考的知识点就是IO密集型与CPU密集型及其对应的线程处理方法。
在IO密集型程序中大量时间花在反复读写文件上,耗费CPU资源并不多;而CPU密集型则程序的大量时间都花在CPU运算上,对文件的读写很少。那么本题中的读硬盘文件和网络发送都属于IO操作,对文件加密则是靠CPU计算的,很耗CPU的,属于CPU密集型操作。
PS:为什么IO操作不耗CPU?
现代计算机的这一操作主要都交给了DMA完成,需要IO时,CPU将要干的事情告诉DMA后就可以释放CPU,让CPU干别的活了,当IO操作完成后DMA会进行中断请求,这时CPU合适时便来接着处理之前IO之后的事情。
所以题目一我是这样作答的:
将文件的读取与网络发送放在线程1中(IO密集型操作),将文件的加密放在线程2中(CPU密集型操作),线程1的优先级高于线程2的优先级;先启动线程1进行读取文件(4个文逐个件依次读取,读完1再读2,以此类推),将读取的数据存放于队列1,再启动线程2对队列1中的数据进行加密,加密后的数据存放于队列2中,线程1中每次读文件后将加密好的数据进行发送。
注:线程1优先级高于线程2的优先级,因为线程2是CPU密集型操作,只有这样当线程2执行时,线程1在需要时才可以被调度到,否则线程1一直占着CPU,其他线程就没法工作了。因为完成加密工作是一直需要CPU参与的,本题只有一个CPU,所以只要一个加密线程就够了,多了反而降低性能。
问题二作答:开4个线程处理读文件和网络发送,分别为线程1、2、3、4;开8个线程用于加密操作,分别为线程a、b、c、d、e、f、g、h。读文件与网络发送的4个线程优先级相同,加密的8个线程优先级相同,但文件读取与网络发送的线程优先级高于加密线程。
线程1读取硬盘1中的文件,存放于队列1中,线程a、b对队列1中的数据进行加密,加密后的数据存放于队列a中,线程1中每4次读操作后对队列a中的数据进行一次网络发送;线程2读取硬盘2中的文件,存放于队列2中,线程c、d对队列2中的数据进行加密,加密后的数据存放于队列b中,线程2中每次读文件后将加密好的数据进行发送;其他依次类推。
问题三作答:即使用2核CPU进行满负荷处理。开1个线程处理读文件和网络发送,分别为线程1;开2个线程用于加密操作,分别为线程a、b。加密的2个线程优先级相同,但文件读取与网络发送的线程优先级高于加密线程。线程1依次读取每个硬盘中的文件(4个文逐个件依次读取,读完1再读2,以此类推),存放于队列1中,线程a、b对队列1中的数据进行加密,加密后的数据存放于队列a中,线程1中每次读文件后将加密好的数据进行发送。



以上是自己的一点分析与作答,欢迎大家回复进行交流与讨论。

1人推荐
随时随地看视频
慕课网APP