仓库源文

.. Kenneth Lee 版权所有 2021

:Authors: Kenneth Lee :Version: 1.0

一些未分类的例子


.. cnote:: :caption: 说明

这里放一批还没有想到放到什么主题中的些例子和思路。

一个“什么设计是架构设计”的例子

最近在评审一组指令的定义,这组指令可以索引两组寄存器,但是部分指令可以用其中一 组,部分可以用两组。我对这个设计很不爽,我觉得这个设计缺乏架构设计,因为我没法 预想这组指令的发展有什么规律。你不能告诉我:你算加法的时候,可以输出到T1寄存器 组,但算减法的时候,就只能输出到T2寄存器。这样我就难想清楚我的代码逻辑怎么构建 了。这样的设计就叫没有架构。我宁愿你说:大部分指令都可以同时访问T1, T2,但有三 个例外……这样可以,因为我基本上避开这三个例外就可以了。或者你说,所有普通指令可 以访问T1,向量质量可以访问T2,T1,T2指令通过某个指令去中转,这个我也能构思怎么 写代码。但如果你每条指令都独立说怎么用T1, T2的,那这个东西就叫没有架构,因为我 没有一个统领的规律去理解它。甚至你每天指令都写出来了,我自己能发现一个规律,我 也不敢用这个规律,因为谁知道你发展以后是什么样的?

所以,架构设计是细节设计不可取代的,架构设计是一个人为的,控制细节“必须呈现规 律”的控制。

外行参与内行讨论的暴论

最近两年听了不少外行参与内行讨论时的暴论,今天(2022-8-22)突然想到要记录一下作 为未来一些写作的例子,我记录在这里:

  1. 讨论某个CPU状态可能会跨特权级的时候由于预测执行泄漏出去,在讨论是否取消这个 设计,有管理者听说了,说这个事情是不是交给特权级设计团队分析一下?这话听起来 就是浪费时间,跨特权级泄漏,和特权级本身的设计的关系不大。这种问题因为听到“ 特权级”几个字,而我们刚好有人设计“特权级”,就要找人设计一下,浪费掉的时间谁 来负责?

  2. 实现了一个新的指令集,但特权级临时使用了另一个Arch的当前定义,为此我们同步找 了另一个团队开始设计新的特权级定义。为了容易思考,某管理者这样总结我们的工作 :我们已经完成了用户态的设计了,现在还缺内核的设计,只要补上了这部分的设计, 我们就成功了……这样描述问题倒是简单了,但这个根本不是现实。指令是用于多个特权 级的,又不是只有用户态。指令和特权级的设计又不是互相独立的,而是互相影响的。 而且指令是一层层细化的,也不是一个隔间一个隔间独立实现,补全以后问题就都解决 的。管理者为了自己思考的方便,作错误的建模,如果做技术的也负荷这种模型去思考, 这个团队就会自己掉入陷阱中。

其他一时想不起来了,等想起来或者收到新的,再慢慢补充吧。

提前决定细节的问题

比如你设计IO设备的IO配置空间,里面有很多功能,比如你需要有域表示endian,有域表 示同步还是异步,有域表示过滤表段地址……等等等等。

架构设计阶段,你马上要决定细节,你也可以给每个这种域一个确定的位置。但这明显是 不对的,因为我们可以把这些域进行组合,让部分功能接近的功能合并到同一个字里面。 如果你非要提前决定这个细节,我们只好把这些域——很多说不定只有一位——让它们每个独 占一个字。

这就是提前决定细节的问题。

多属性问题

今天收到一个任务,管理层让我报告一下某个项目的执行进展。我开始写一个汇报胶片,在 这个汇报的“背景介绍”章节,我有这么几个目的:

  1. 管理层希望知道项目的执行情况,我要告诉他们这个执行情况。

  2. 我自己也正需要对项目的逻辑进行一次Review,看看有没有走偏。

  3. 最近有一些声音,说我们这个项目应该走另一个方向,我们正需要回复一下这种声音。

你看,这些全部都是实实在在的我的投资的动力,然则,这里面哪个是“主要矛盾”呢?显 然是第二个,因为1和3都需要通过2来解决。

也许你会有一些腹黑的判断,比如你会认为,管理层其实不是要知道项目的执行情况,而 是管理层没钱了,要找个理由把项目灭掉。或者3里面那些人是为了政治斗争,为自己的项 目争资源。但从一个“正道”的角度来说,2还是最稳的动力。要解决1,3的问题,仍是先解 决第2个问题。

到我们确切写报告的内容的时候,2是主逻辑,2已经回答的1、3的问题,我们就不用管了, 但如果还有一些证据可以增强1和3的答案,我们可以在主逻辑之外补上去。

这就是构架师解决多个属性问题的方法,所以我们所架构师的解决方案是立体的,代码的 解决方案是拍扁的。

从权问题

今天女儿进学校的时候,家长系统发过来一个消息,说她已经离校。这明显是个状态处理 错误。这让我有了这个感慨:

架构设计很反直觉,因为它设计的是多个视图独立的逻辑。在某个视图上成立,在其他视 图上不一定成立。我们只是设计一个权衡的机会。比如前面这个问题,我可以评价说,这 个设计工程师“烂”,因为这种层次的错误,在模块级别就应该被单元测试发现出来了。不 可能出现在客户面前,更不要说连续很久地出现在客户面前。但如果我作为这个方案的架 构师这种问题是否出现,完全取决于我有多少钱做这个项目,以及这个团队的水平。毕竟 这个问题出现在逻辑的枝叶上,它还没有识别错人,没有死机。后面这些问题更严重。

这是一个例子,说明你说(或者说认为)什么是对的,和你选择做什么,这是分离的。

名可名的另一个例子

有一个硬件架构定义,有人描述一个功能的时候,说操作系统进行切换的时候,必须保存 某个状态。我给他的评价说,“你说好你的行为就好了,操作系统要不要保存某个状态不关 你的事,你不知道操作系统会怎么做”。这位兄弟听了非常激动,“我怎么就不懂操作系统 了?我曾经开发过xxxxxxx,我还发表过xxxx,xxxx……”。

他觉得我在说他懂不懂操作系统,而我其实说的是,你在定义一个硬件的时候,你只“知道 ”这个硬件的本身,操作系统会怎么做,你不知道。就算你是业界一流的操作系统专家,你 也不知道用你这个硬件的操作系统会怎么样,因为这另外有人在设计,这玩意儿他遇到问 题是会修改的,你再牛,你也管不着这个细节。

所以,我说他不知道“操作系统”,说的是他控制不了操作系统的所有细节,他要求操作系 统必须有上下文切换,这个上下文切换确切会干什么,甚至有没有这个切换,都不在他的 定义范围内。他能严格定义的,只有他自己的行为是什么样的。他一旦陷入别人的定义, 他的定义就没法严格了。

所以,“懂不懂操作系统”,换一个目的,表达的那个意思是完全不同的。这是名可名从目 标上看的一个例子。

什么是为展现的逻辑

这是一个针对“能跑就行”的反例,说明什么是被盖住的逻辑。有一个经典问题:你妈和媳 妇掉水里,你先救谁?

这个问题最好的解决方案是:

  1. 我不让她们掉水里。这叫治未病。

  2. 把他们同时救上来。

解决问题不能被问题本身牵引了,如果我把两个问题同时解决了,这个“优先级”这个问题 就不存在。

但程序要考虑所有可能性,所以考虑程序的问题,所有可能性都在范围内。那,“你先救谁 ?”

我不想回答这个问题,因为对于架构师来说,我们不制造问题去让自己掉坑里。但我要提 出这个问题给你,只是为了告诉你,这就是“被盖住的逻辑”。架构师解决问题,不是可以 完美解决每个问题,而是让我们不需要去解决那个问题,但如果你不面对那个问题,你就 解决不了那个问题。

架构的减熵属性

过去讲架构总是强调它在高级层面上符合需求的属性,但很少强调它的减熵属性本身。但 这个条件是我们做概念空间建模的依据。

我们设计一个函数,一个数据结构,里面什么逻辑都可以放,放进去都可以实现功能,但 为什么我们会选择把一些逻辑放在一起,我们我们就算浪费一些逻辑,都要让某个逻辑呈 现成某个样子?在满足目标之外,我们还有什么目标?

这就是减熵,如果我们引入“复位”这个属性,所有其他缓存,Gated,迁移的设计都对其到 这个属性上,那么我们作为控制者,只要做这一个动作,其他细节都不需要关心,这个系 统对维护者来说熵低,这我们感觉上构架就好。这个感觉反映的是它的维护成本。

熵低不是简单体现在被分析的系统的内部的,它更多体现在控制者自身的逻辑上。比如我 们建“电梯算法”这样一个概念,不是因为电梯算法本身的信息量少,而是控制者本身已经 有电梯是怎么工作的这个逻辑了。复用这个逻辑,对控制者来说,被控制系统具有“规律” 。这是我们做架构设计的另一面。

黑盒和明盒

经常遇到这种情况:比如有人问我,你明天去春游吗?我回答不了,因为我还没有排过明 天的计划,想想明天要干什么?:要完成一个报告,可能要30分钟,要去健身房,不过既 然春游,不去健身房也可以……没有其他了,好吧,可以去春游。

这些条件其实都知道,但我却没有立即“去不去”这个结论,没有前面这个“思考”的过程, 我们不知道这能否做到。

架构设计也是一样的,已经知道手上有key和链表头了,我能不能拿到某个节点的内容呢? 没有进行逻辑设计钱,我们并没有信心。我们设计了,我们照亮了这个黑盒,让它变成明盒。

但这同时又是个度的问题,没有实际去参加春游,没有代码写出来,我们其实不肯定是不 是去春游就不会遗漏下什么, 不肯定有key和链表头能否拿到节点。

这个问题我想明白了,但有什么用?我暂时不知道。在没有想明白前,我不知道,只是个 黑盒,但至少现在我已经照亮它了。