企业应用中的计算(上)

企业应用系统,尤其是金融保险行业的应用系统,常常会涉及大量繁杂的计算。例如,在保险行业,客户购买了一份投连保险产品,系统要为客户展示未来数十年的利益。这些利益按月计算,按年累计,各项金额前后关联,计算形态多种多样。这类保险产品的利益展示可能涉及万千次的计算。如果这些计算没有经过良好的设计,系统的性能常常会变得低效。

计算是软件行业中的一个重要领域。对于企业应用系统来说,计算不仅包含了算法,还包含了一套应用算法的框架。仍以保险行业为例,保险产品形形色色,计算规则、计算公式、计算过程千差万别。计算框架要有能力对这些看似繁杂无序的内容做出归纳和抽象,以最小的代价容纳它们,并使之享受到算法的好处。

值得强调的是,计算框架和算法是计算领域中两个不同的子领域。这两个子领域的目标和内容都是不同的。计算框架试图容纳变化,并使之用到算法的好处;算法则是基于一套数据结构,在空间和速度的权衡下进行高效计算。清晰的领域划分可以使我们更加专注在领域内的工作,而模糊的领域认识,常常会使我们迷失方向,做出错误的选择。在实践中,我们常常看到计算框架和算法之间没有明显的边界,算法中嵌入计算框架的元素,这使得算法无法进行充分优化。

最近,我正在设计一个计算服务。面对数百页各类产品的业务计算说明,从中找到计算特征,提炼高效的算法,并设计一个框架来容纳各种变化,这真的是一次有趣的挑战。由于具体的业务内容不适合公开展示,因此,本文将只是着眼于计算设计的方法和高度抽象的算法模型。

了解业务领域,熟悉业务需求,当然是软件开发的前提。接下来,我们需要从繁杂的业务描述中找到计算特征。我不知道这一步是否有可供操作的方法,事实上,我发现这似乎是经验积累后的一种转化。当你阅读需求的时候,很多工作已经在头脑中自然地展开,识别、判断、证实、归类、忽略、抽象,一些想法渐渐从模糊到清晰。好吧,我得到了未经处理的计算特征。见图1。

图1

从图1可知,一组计算子(通过计算获得,计算形态不限)将作为输入块(A)。这些计算子之间存在依赖关系,即某些计算子通过其他的计算子参与才能完成计算。这种依赖关系可能是多级的,例如,计算子1依赖于计算子2,计算子2依赖于计算子3。

这一组计算子被送入下方紧邻的一个计算块(B),这个计算块(B)内部的计算子之间不仅存在输入块(A)中的计算子规则,还可能会依赖输入块(A)中的计算子。

当前的计算块(B)会被送入其下方紧邻的另一个计算块(B'),计算块(B')不仅像计算块(B)一样,依赖于输入块(A),还依赖于计算块(B)。

计算块(B)还会被送入其右方紧邻的计算块(C),计算块(C)和计算块(B’)类似,依赖于输入块(A)和计算块(B)。

计算块(C)会被送入其下方紧邻的计算块(C’),计算块(C’)依赖于输入块(A),计算块(C),计算块(B’)。

上述这种规则将沿着Y轴向右方延伸,沿着X轴向下方延伸。

最终,数据将到达输出块(O)。输出块(O)与输入块(A)及紧邻其上方的一排计算块有依赖关系。

上述计算特征表明,这类计算的难点在于计算子之间的依赖关系。这些繁杂的依赖关系如果没有经过清晰的梳理,会使你不得不保存大量的历史数据,并不得不进行串行化的低效计算。失控的大空间,以及闲置的CPU计算能力,对于算法来说都是致命的缺陷。

在总结出计算特征后,我们将开始算法设计。算法设计通常以硬件资源为基础(一台40核的服务器可供使用)。我们采用了并行计算,并确立了一个基本原则,即以最大限度并行计算为优先,换句话说,不是以业务逻辑为优先。这个基本原则要求我们必须在更高层次上进行抽象,确保只有在无法避免时才进入串行计算。显然,由于计算特征中的依赖关系,我们很难完全避免这一点。不过,从另一个角度来看,这种缺陷未尝不是一件好事,完全占用CPU会导致其他的严重问题,我们必须留出CPU的计算能力给其他的并发请求。现在,我们的并行计算模型像是一个锯齿形,见图2,对比了串行计算和锯齿形并行计算。

图2

算法设计和业务领域的设计有些类似,两者都需要对数据(结构)进行建模,并基于数据模型进行逻辑处理。不同之处在于,算法显然更偏向于求值计算,而且更加关注指令的简洁和内存空间的使用。任何设计都不是一蹴而就,你需要在头脑中设想计算的过程,并不断迭代,最终提炼出恰当的概念来容纳你对于计算的描述。事实上,我同样不知道该如何针对这个过程给出可操作的具体方法。总之,我构思了这些概念,见图3。

图3

我们将有一个计算的上下文(Calculation Context),这个上下文包含了输入(Input),输出(Output),以及一组计算布局(Calculation Layout)。每一个计算布局都可以迭代执行,执行的结果会进入计算布局栈区(Calculation Layout Stack Area),栈区的数据来自于并行计算区(Calculation Parallel Area),由于并行计算,栈区的数据是无序的,需要经过后续处理,进入计算布局输出(Calculation Layout Output)。一个计算布局包含了多个有序的并行计算区。每一个计算区又包含了多个计算分组(Calculation Item Group),这些计算分组是有序的,而每个计算分组又包含了多个计算子(Calculation Item),这些计算子是无序的。理论上,无序的分组都是可以进行并行计算的。

当有了这套数据模型后,我们的算法实现就变得相对简单了。当然,在算法实现过程中,仍然有很多算法领域内的问题需要给出答案。例如,如何保证尽可能少地占用内存空间?如何采用最合适的基本数据结构?如何使指令变得最大限度的精简?

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,294评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,493评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,790评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,595评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,718评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,906评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,053评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,797评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,250评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,570评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,711评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,388评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,018评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,796评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,023评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,461评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,595评论 2 350

推荐阅读更多精彩内容