问题原因:

最近由于工作实际需求,需要对某个计算单元的计算方法进行重构。原因是由于这个计算单元的计算耗时较长,单个计算耗时大约在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. 关于codeMirror插件使用的一个坑

    codeMirror插件可以做语法高亮渲染,但它操作过程是这样的:先从 textarea中读取值放到codemirror动态生成的div中,根据textarea中的换行个数确定行数,根据正则表达来高亮 ...

  2. iptables详细说明

    一:前言 防火墙,其实说白了讲,就是用于实现Linux下访问控制的功能的,它分为硬件的或者软件的防火墙两种.无论是在哪个网络中,防火墙工作的地方一定是在网络的边缘.而我们的任务就是需要去定义到底防火墙 ...

  3. 窗口 - dialog - 与后端交互

    与后端交互,一般需要提交表单数据,所以,这次渲染得dialog其实是一个<form> <form id="loginForm"> <table ali ...

  4. IO调度器

    由于对blktrace的好奇,来到了block层.通过阅读block层的代码,自己的几个错误认知被纠正,比如 一) 同步操作时,进程是在驱动中睡觉真实情况是:进程在文件系统睡觉 二) 对同一个数据块的 ...

  5. Vs2013中通过Nuget添加不同版本jQuery

    vs2013中如果直接更新jQuery则是2X的版本,为了兼容IE浏览器的,一般都是希望使用jQuery1.x版本的jQuery,则可在调出Nuget的控制台,在控制台输入(此例子是下载jQuery ...

  6. Oracle字符分隔函数(split)

    为了让 PL/SQL 函数返回数据的多个行,必须通过返回一个 REF CURSOR 或一个数据集合来完成.REF CURSOR 的这种情况局限于可以从查询中选择的数据,而整个集合在可以返回前,必须进行 ...

  7. 学习C++.Primer.Plus 4 复合类型

    本章介绍的有复合类型有: 数组. 字符串. 结构. 共用体. 指针 数组: 声明数组时数组长度必须为常量(或const). 只有初始化时可以用“=”,其它时候均不可以给数组直接赋值,除了赋值的元素以外 ...

  8. swift导航栏导航按钮添加多个按钮事件

    //导航左边返回按钮 let button1 = UIButton(frame:CGRectMake(0, 0, 18, 18)) button1.setImage(Constant.Image.Na ...

  9. STM32 控制红外线收发

    买了一块STM32的板子,这次需要将IR的code移植到STM32上面,因为STM32成本比树莓派低得多,所以 一些简单的外设挂在STM32上就行了. 我买的板子的型号是STM32F103C8T6,价 ...

  10. 【Alpha版本】十天冲刺集结令

    031402304 陈燊 031402342 许玲玲 031402337 胡心颖 03140241 王婷婷 031402203 陈齐民 031402209 黄伟炜 031402233 郑扬涛 [Alp ...