.. Kenneth Lee 版权所有 2019-2020
:Authors: Kenneth Lee :Version: 1.0
限制的可移动性
本文是这个文档的一个补充::doc:限制管理
。
想到要讨论这个问题,是因为最近和人讨论一个设计,发现很多问题,特别是对架构师, 或者对软件工程师来说是显而易见的问题,对部分设计师,特别是芯片设计师来说,居然 是“很难理解”的。这让我体会到,上面那个表述,可能抽象得太高了,我们还需要讨论一 些最基本的原理。
有芯片设计的同事常常这样跟我说:“计算10M的数据,比计算100M的数据快,这不是显而 易见的事情吗?”,“不能一次输入超过计算芯片的最大Buffer的数据,这不也是显而易见 的事情吗?”……但同时他们又常常这样跟我说:“数据多大是个黑盒,你们做软件的不用知 道,交给我们就好了”,“缓冲区多大是个黑盒,你们做软件的不用知道,交给我们就好了” ……
这些想法,和软件人员,特别是高层软件设计人员的理解,是完全在另一个世界里的。正 如前面那个文档说提到的,对软件人员来说,逻辑链的根,是建在“限制”上的,如果我们 不知道真正的限制者是谁,我们就无法处理“变化”。
我举个例子,假设有下面这样一个数据流:
.. figure:: _static/数据流例子.jpg
我们经过A-B-C-D四个软件模块的内部限制到达输出,最后能成功到达输出的数据(也许经 过了变换,这个和我们主题无关,先忽略),对软件来说,A、B、C、D都是CPU上运行的, 都是可以改变的东西,你说我把i3的限制前移到A模块上,有什么困难吗?——除了代码升级 本身,根本没有。
所以,软件设计师,特别是软件构架师。我们其实很不在乎“名份”,我们在乎实际的结果 。你开发B模块的人要生要死说i3多重要,如何如何有必要,我把它前移或者后移到其他模 块去,完全看有没有需要——多大点事啊?
这个事情,推广到全系统的构架师,某个逻辑是要放到软件一方,还是放到硬件一方——这 多大点的事啊?你以为你做硬件,这个东西就“硬”了?只要你的对手做出一个更能被接受 的方案(无论是因为性能还是成本还是TTM),这种东西说变就变了。金玉满堂,莫之能守 ——“量”不能保证你的安全的。“势”才能保证你的安全。“势”是竞争力和改变的难度。
所以,系统构架需要有限制管理,比如上面这个图中i5的限制,完全就可以不考虑(但它 内部可能仍有这个限制),所以我把它放在后面,它就可以少很多保护,默认认为i5不会 发生就可以了,这样整个系统的效率才会高。如果前置模块接受我内部有Cache大小的限制 ,在提供数据的时候就已经考虑到我的Cache要素了,我的模块的性能就可能高,但你要充 大头怪,说你是黑盒,前置模块给了你数据,你性能又高不起来,你说前置模块太蠢,不 会“用”你这个模块?你是觉得你是白莲花呢?还是觉得你是覆巢之下的完卵?
所以,“处理10M比处理100M快”,这是谁的“限制”?我一个用户,我就想把数据从一个节点 发到另一个节点去,你中间有很多障碍,但那是你这个通道的障碍,不是我用户引入的障 碍,你100M发得比10M慢,这可不是我用户(前置模块)给你引入的限制,这是你自己引入 的限制。你不能认为这个事情“顺理成章”。如果你的系统是无论多大的包,都是打包成1G 的Burst统一发送的,100M和10M的速度就是一样的,谁告诉你这是“顺理成章”的事情啊?
除非我的用户要求,发完10M以后,才能发第二个10M,这才是用户引入的限制。因为无论 换谁来做这个通道,它都改变不了这个障碍。
了解障碍是软件架构师非常重要的工作。因为如果我不能摸到你的“核心限制”,我就没有 办法决定用力的轻重,我辛苦苦苦说服用户接受你的Buffer Size是10M,用户所有软件的 切分都以这个为中心,以此建立了1000KLoc的代码。然后你跟我说你升级为100M?用户会 让你去死!
这是整个架构设计的核心,简单看上面这个逻辑,我们可以说,Buffer Size是个变量,可 以基于它是变量来进行设计,但所有的“优化”都来自固定的东西,你“变量”越多,开发成 本就越多,开发成本上去了,竞争力又下去了。如果和Buffer Size相关的代码涉及的代码 只有100行,把这个东西当做“变量”来做,这就成了浪费了。
所以架构设计是经验为基础的艺术,如果它能被你简单抽象出Pattern,它就不是架构了, 那些是工程。所以你想学架构设计的Pattern?觉得你学两本Pattern,UML的书就搞懂架构 设计?想太多了。
所以,架构师和你讨论设计,必然是要摸你的真实限制是什么的。你不要动不动告诉我你 是个黑盒,你如果真是个黑盒,我很高兴,因为这样我就没有什么好考虑的,但你一次次 不靠谱,事后告诉我(或者周边模块)给你的数据其实没有让你达到最优,那时我就无能 为力了。你也不要跟我说你对周围的模块没有办法,是他们要这样的接口的,因为他们也 是一样说你的。你们这些互相指责都不是真实的限制,只是你们人为制造出来的。我们用 真正的环境限制来限制自己,不用人心和自己所处的位置来限制自己,否则你走不长。你 要摸清你的限制,就先要求上级输入给你“完美”的数据来做你输入,完全按你的要求来, 让你的性能达到最优,然后我们再来看为什么上一级给不了你这个输入,这样我们就摸到 我们真实的障碍是什么了。人家都还没有说不行呢,你就说人家能给你的输入就是这样的 ,说到底是你懒得想而已。你以为你解释得通这个问题就不存在了?竞争对手分分钟教你 做人。
其实,这些观点虽然看起来是架构师的观点,但实际上是模块设计师同样必须考量的,因 为你也不想老修改你的模块呐。
上面的概念说起来复杂,如果你只是做模块设计(或者做硬件接口设计),我其实就期望 一点,你建立概念,建立在你真正的硬件约束上。比如,你跟我说,“虚拟机给硬件寄存器 写入XXX”,这个就很可能是我无法接受的。“虚拟机”这个概念,我认为根本就不关你硬件 的事情,你怎么知道我软件侧是怎么定义“虚拟机”这个概念的?你怎么知道我是虚拟机里 面给你写的XXX?你一旦用了“虚拟机”这样的表达,就产生了一个对我虚拟机设计产生了一 个限制。我不反对有这样的限制,问题,这个限制得真的是你的限制,要不就是竞争对手 也得这样干,要不就是你加入这个限制后,你的Die Size变小了,性能变高了,我都行。 但很多时候,其实你根本就是图说得爽脆,给我引入一个限制,却不能带来你的竞争优势 ,这一个小动作,就把我们的竞争力给毁了。
还有那些动不动就给帮我考虑好怎么设计线程,然后怎么调用runtime,然后写到你的调度 队列中的硬件设计师——我怎么放我的Runtime,放不放这个Runtime,在不在一个进程之内 ,这些都和你无关,你就是个外行,除非我不这样干,你就不能工作,否则轻易不要跳过 来,我才是这个领域的专家,你根本就不懂,你不为这个设计负责,却去为这个设计增加 限制,这个限制不是给我的,这个限制是给整个系统的呀。没有经验的人给有经验的人设 置限制,这怎么可能达成系统的最优呢(注:这里的“我”不是说我本人,只是描述的方便 。也不是说不能讨论别人的设计,而是说,守着自己的限制,就用来建自己这个模块的逻 辑,不要随意去给别人增加限制,这样才能让专业的人做那个专业的事情)
看完本文的表述,不知道各位读者对下面这个文档的DFD方法是否会有更深的理解了?
:doc:`两种基本的构架表述方法`