问题原因:

最近由于工作实际需求,需要对某个计算单元的计算方法进行重构。原因是由于这个计算单元的计算耗时较长,单个计算耗时大约在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密集型任务,异步化及并行计算等优化方法很难进行,并且提高会非常有限(计算密集型任务),因此,通过对原子任务本身的优化来达到最终目标也是一个重要的思路。

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

  1. 浅谈Java两种并发类型——计算密集型与IO密集型

    转载:https://blog.csdn.net/u013070853/article/details/49304099 核心是可以分别独立运行程序指令的计算单元.线程是操作系统能够进行运算调度的最小 ...

  2. Python IO密集型任务、计算密集型任务,以及多线程、多进程

    对于IO密集型任务: 直接执行用时:10.0333秒 多线程执行用时:4.0156秒 多进程执行用时:5.0182秒 说明多线程适合IO密集型任务. 对于计算密集型任务 直接执行用时:10.0273秒 ...

  3. IO密集型 计算密集型

    参考:https://www.cnblogs.com/zhangyux/p/6195860.html 参考:廖雪峰 协程 gevent IO密集型任务指的是磁盘IO或者网络IO占主要的任务,计算量很小 ...

  4. [Python]IO密集型任务 VS 计算密集型任务

    所谓IO密集型任务,是指磁盘IO.网络IO占主要的任务,计算量很小.比如请求网页.读写文件等.当然我们在Python中可以利用sleep达到IO密集型任务的目的. 所谓计算密集型任务,是指CPU计算占 ...

  5. cpu,io密集型计算概念

    I/O密集型 (CPU-bound) I/O bound 指的是系统的CPU效能相对硬盘/内存的效能要好很多,此时,系统运作,大部分的状况是 CPU 在等 I/O (硬盘/内存) 的读/写,此时 CP ...

  6. CPU计算密集型和IO密集型

    CPU计算密集型和IO密集型 第一种任务的类型是计算密集型任务,其特点是要进行大量的计算,消耗CPU资源,比如计算圆周率.对视频进行高清解码等等,全靠CPU的运算能力.这种计算密集型任务虽然也可以用多 ...

  7. 题外话:计算密集型 vs IO密集型

    我们把任务分为计算密集型和IO密集型,erlang作为IO密集型的语言,适合网关等相关的场景,而对计算达到某一量级后,可能处理效率下降的很明显. erlang不适合数值计算.erlang是解释型的,虽 ...

  8. 计算密集型和 io 密集型项目的使用场景分析和代码演示

    from threading import Thread from multiprocessing import Process import time 计算密集型 def work1(): res= ...

  9. 并发编程~~~多线程~~~计算密集型 / IO密集型的效率, 多线程实现socket通信

    一 验证计算密集型 / IO密集型的效率 IO密集型: IO密集型: 单个进程的多线程的并发效率高. 计算密集型: 计算密集型: 多进程的并发并行效率高. 二 多线程实现socket通信 服务器端: ...

随机推荐

  1. 03 Hibernate错题分析

    1.在Hibernate中,以下关于主键生成器说法错误的是( C). A.increment可以用于类型为long.short或byte的主键 B.identity用于如SQL Server.DB2. ...

  2. AC日记——找第一个只出现一次的字符 openjudge 1.7 02

    02:找第一个只出现一次的字符 总时间限制:  1000ms 内存限制:  65536kB 描述 给定一个只包含小写字母的字符串,请你找到第一个仅出现一次的字符.如果没有,输出no. 输入 一个字符串 ...

  3. U3D的飞船太空射击例子中,使用coroutine

    coroutine 协同程序与线程差不多,也就是一条执行序列,拥有自己独立的栈,局部变量和指令指针,同时又与其它协同程序共享全局变量和其它大部分东西.线程与协同程序的主要区别在于,一个具有多线程的程序 ...

  4. 如何用patch打补丁

    patch -p1 < *.patch -p1代表忽略第一层目录(patch文件中的).

  5. SQL 2008 windows登录失败,错误18456, 更正

    可能的原因:密码有效性验证失败.该密码太短,不符合 Windows 策略要求. 本地设置可能被域设置覆盖.而域设置中指定了安全策略,密码必须有一定的复杂性.重新更改sa密码. 第一步.以windows ...

  6. [No000048]程序员的成长过程中,有哪些阶段?

    有人在 Quora 提问,并补充: 有木有朋友能根据你们自身经历,清晰地划分各个阶段?比如:学习第一门编程语言.第一份工作.职业决策.理解 IT 公司的目标,等等. Quincy Larson 的回复 ...

  7. 利用MySQL存储过程分割字符串

    (转)http://tec.5lulu.com/detail/104krn1e6p2w78d77.html 现有一段字符串,如apple,banana,orange,pears,grape,要把它按照 ...

  8. vijos1907[noip2014]飞扬的小鸟(完全背包)

    描述 Flappy Bird 是一款风靡一时的休闲手机游戏.玩家需要不断控制点击手机屏幕的频率来调节小鸟的飞行高度,让小鸟顺利通过画面右方的管道缝隙.如果小鸟一不小心撞到了水管或者掉在地上的话,便宣告 ...

  9. ie 7/8不支持trim的属性的解决方案

    if(!('trim' in String.prototype)){ String.prototype.trim = function(){ return this.replace(/^[\s\uFE ...

  10. listview1

    Edit1.Text := listview1.Items[i].Caption; //读第i行第1列 Edit2.Text := listview1.Items[i].SubItems.string ...