计算&IO密集型任务的 优化

问题原因:

最近由于工作实际需求,需要对某个计算单元的计算方法进行重构。原因是由于这个计算单元的计算耗时较长,单个计算耗时大约在1s-2s之间,而新的需求下,要求在20s内对大约1500个计算单元计算完毕。如果不对原有计算单元的计算方法进行优化及效率提升,那么以8核CPU(超线程16线程)来说,在单个计算1s的理想条件,服务器16线程完成任务的理论上限也需要90s+,何况多线程还并不是简单的效率叠加,实际测试情况下,耗时往往在150s以上。因此,对原有计算单元的计算优化是必须的。

问题分析:

通过对原有计算单元的实现过程查看,计算任务存在大量的数据库读取及大量的比对、计算等操作,涉及的数据表的数量级从数百到百万不等,这些数据表有一个相同的特点就是相对固定,并不是实时业务数据。通过对原有计算过程的分析,主要的耗时就在各种条件比对及比对后进行的数据库IO操作。

因此,要提高效率,首先想到的就是如何减少数据库的IO次数,但实际的计算任务是一个很严格的时序型逻辑,即每一步的处理输入是上一步的数据处理结果。因此要在单个计算任务中进行并行计算的改造很难,并且,由于单次数据库IO的时间开销也不大,因此进行异步化改造也不合适,反而会增加代码的复杂度。

所以最终还是把思路集中在如何对计算任务本身进行优化。

解决方式:

经过对计算任务的分析,在这种场景上下文中,决定以哈希定位作为解决方式(这是一种可能的解决方式,但并不一定是最优的)。

通过前文对计算任务的分析,所涉及的数据都是相对固定的,因此首先考虑将所有数据加载到内存(由于数据量并不是非常的大,服务器内存还能承受,可根据实际需求加载到mem或redis中)。如果仅仅是将数据加载到内存,再用linq2object替代原有的数据库IO,提升并不大,因为计算逻辑中最耗时的操作是对数据的范围查询,即数据并没有精确匹配,而是需要找到目标值对应数据的上下限,并进行线性插值运算。

如果能将范围数据查询的工作以更快速更精确的方式来实现,就省下了计算逻辑中最大的时间开销。因此考虑才用呢哈希定位的方式进行。

具体改造过程不再赘述,工作难点主要在于哈希KEY的构造,以及如何通过哈希寻址实现数据库查询中的‘> and <’条件操作。具体来说,通过将范围值扩大量纲变为整数,并以最小步长提前做线性插值,即可形成满足要求的哈希KEY,同时,通过对需要定位的值,对步长进行除法取整,即可得到目标值的下限值,再对下限值加上步长,即可得到上限值,从而通过一次哈希寻址,得到之前需要在数据库进行‘> and <’操作的结果。

解决结果:

通过以上改造,在该计算任务场景中,对1000+计算单元进行计算的时间开销已降低到1-4秒(由于是WCF服务调用,因此需要视网络通信等状况而定),完全可以满足需求。

通过对这次计算任务的重构,可以看出,对计算密集型/IO密集型任务,异步化及并行计算等优化方法很难进行,并且提高会非常有限(计算密集型任务),因此,通过对原子任务本身的优化来达到最终目标也是一个重要的思路。

时间: 2024-08-05 18:24:05

计算&IO密集型任务的 优化的相关文章

数据库 IO密集型 与 CPU密集型

1.IO密集型: 数据库仅提供建立的查询插入等操作,复杂的业务逻辑依赖与程序的实现,需要程序与数据库的频繁交互 2.CPU密集型: 一些复杂的逻辑计算可以在数据库中进行处理,可以依赖与数据库端的存储过程,触发器等功能,减少了程序代码与数据库的交互,减轻访问数据 库带来的IO压力,对于装备有高速磁盘阵列的服务器来说,可以实现CPU密集型 对于目前,高并发,数据量大的动态网站来说,数据库应该为IO密集型. http://blog.chinaunix.net/uid-116213-id-3086203

什么是CPU密集型、IO密集型?(转发)

CPU密集型(CPU-bound) CPU密集型也叫计算密集型,指的是系统的硬盘.内存性能相对CPU要好很多,此时,系统运作大部分的状况是CPU Loading 100%,CPU要读/写I/O(硬盘/内存),I/O在很短的时间就可以完成,而CPU还有许多运算要处理,CPU Loading很高. 在多重程序系统中,大部份时间用来做计算.逻辑判断等CPU动作的程序称之CPU bound.例如一个计算圆周率至小数点一千位以下的程序,在执行的过程当中绝大部份时间用在三角函数和开根号的计算,便是属于CPU

CPU密集型、IO密集型

CPU密集型(CPU-bound) CPU密集型也叫计算密集型,指的是系统的硬盘.内存性能相对CPU要好很多,此时,系统运作大部分的状况是CPU Loading 100%,CPU要读/写I/O(硬盘/内存), I/O在很短的时间就可以完成,而CPU还有许多运算要处理,CPU Loading很高. IO密集型(I/O bound) IO密集型指的是系统的CPU性能相对硬盘.内存要好很多,此时,系统运作,大部分的状况是CPU在等I/O (硬盘/内存) 的读/写操作,此时CPU Loading并不高

Python的进程和线程(二)——IO密集型任务

一.什么是IO密集型任务? 主要的核心任务是进行IO操作,比如写文件,进行磁盘的读写等等. 上一篇博客,对计算密集型任务,多线程并没有体现它的好处,反而话费的时间更长.对IO密集型任务多线程会有明显的优势 二.举例: 任务:爬取韩寒的博客 1.获取urls, 2.根据文章的url,爬取内容,保存文件 3.将urls分给不同的进程/线程 4.多进程/多线程爬取 step1:爬取urls 思路:用requests库来爬取页面,用beautifulSoup库来获取目标的urls值 import req

什么是CPU密集型、IO密集型?

CPU密集型(CPU-bound) CPU密集型也叫计算密集型,指的是系统的硬盘.内存性能相对CPU要好很多,此时,系统运作大部分的状况是CPU Loading 100%,CPU要读/写I/O(硬盘/内存),I/O在很短的时间就可以完成,而CPU还有许多运算要处理,CPU Loading很高. 在多重程序系统中,大部份时间用来做计算.逻辑判断等CPU动作的程序称之CPU bound.例如一个计算圆周率至小数点一千位以下的程序,在执行的过程当中绝大部份时间用在三角函数和开根号的计算,便是属于CPU

JAVA之IO技术转换流方式优化键盘录入InputStreamReader,OutputStreamReader

package ioTest.io2; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; /* * 在Readin这个类(读取键盘录入的最基础的方法类)的末尾,我们提出了一个

影响IO密集型应用性能的因素

如果我们曾经在IO密集型应用中碰到过性能问题,那么我们可能都知道系统的性能会随磁盘压力增加而降低.这个因素是众所周知的,但是其背后的原因可能就不那么清晰了.本文将尝试解释这个过程背后所发生的事情. 一个典型的场景是当数据被写入一个文件时,它首先会被写入内存区域保留页面缓存:该缓存页保存还没有被写入的数据,这些数据被称为脏数据:经过一段事件后,根据IO策略,系统内核将这些脏数据刷新到持久化到硬盘的设备队列中.一旦数据到达队列,剩下的就是机器操作:设备驱动读取IO请求.接着是旋转,寻找和写入到文件所

IO密集型操作时,为什么线程比进程更好?

在IO密集型的操作时,进程线程都不会太占用CPU,但是进程消耗的资源比较多. 原文地址:https://www.cnblogs.com/apollo1616/p/10206063.html

数据库操作是IO密集型的论证

一.iostat 背景是我们在进行大量的数据更新操作,以此来查看磁盘的状态情况.我们查看磁盘IO,也主要是通过iostat 这个命令来进行查看. iostat -d -k 1 5 -d 表示,显示设备(磁盘)使用状态,去掉可以和CPU状态一起显示:-k某些使用block为单位的列强制使用Kilobytes为单位,改为-m(以MB为单位展示):1 5表示,数据显示每隔1秒刷新一次,共显示10次. [[email protected] ~]# iostat -d -k 1 5 Linux 3.10.