问题原因:

最近由于工作实际需求,需要对某个计算单元的计算方法进行重构。原因是由于这个计算单元的计算耗时较长,单个计算耗时大约在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. UNITY3D的变量初始化问题

    大部分是代码声明变量,而变量的初始化值在编辑器中指定,不在代码中直接指定 奇怪! 而且只有Public的才能在编辑器中出现,如果你改为Private就不再显示,如果你再改回PUBLIC,原先指定的初化 ...

  2. 用FLASH,安智和IOS打电话方法

     打电话?你直接urlrequest不就打出去了吗普通网页http://xxx电话tel://xxx要啥ane 

  3. createDocumentFragment() 创建文档碎片节点

    var aqiData = [ ["北京", 90], ["上海", 50], ["福州", 10], ["广州", 5 ...

  4. Android图片异步加载框架Android-Universal-Image-Loader

    版权声明:本文为博主原创文章,未经博主允许不得转载. Android-Universal-Image-Loader是一个图片异步加载,缓存和显示的框架.这个框架已经被很多开发者所使用,是最常用的几个 ...

  5. 内裤:DataTable转Model

    public class ConvertHelper<T> where T : new() { /// <summary> /// 利用反射和泛型 /// </summa ...

  6. Linux下命令行安装配置android sdk

    首先, 你得有个VPN 参考以下三篇完成Android SDK的安装 https://www.digitalocean.com/community/tutorials/how-to-build-and ...

  7. Centos5.8 安装 Redmine

    安装Ruby 到 /opt/ruby-2.0.0 -p481.tar.gz cd ruby--p481 ./configure --prefix=/opt/ruby- sudo make sudo m ...

  8. MYSQL临时表创建索引

    DROP TEMPORARY TABLE IF EXISTS tmp_record_t2;CREATE TEMPORARY TABLE tmp_record_t2(consumption_id INT ...

  9. Paxos变种和优化

    分布式系统理论进阶 - Paxos变种和优化 引言 <分布式系统理论进阶 - Paxos>中我们了解了Basic Paxos.Multi Paxos的基本原理,但如果想把Paxos应用于工 ...

  10. ACM水题

    ACM小白...非常费劲儿的学习中,我觉得目前我能做出来的都可以划分在水题的范围中...不断做,不断总结,随时更新 POJ: 1004 Financial Management 求平均值 杭电OJ: ...