软件接口设计_接口定义的工作模型 接口定义是架构的最终结果。实际上,架构的外在表现常常表现为接口。我们用SDSA方法来看这个问题,可以这样看:作为计算系统,你的核心需求必然是数据加工。无论这个功能看起来多不像一个计算,计算机系统能干的也就是数据加工。我们拿一个计算辅助功能来举例,比如说,MMU。用DFD来讨论MMU功能,它是这样的:
MMU处理的DFD图,上图是Context Diagram,下图是DFD。如果你觉得这个图缺了缺页流程,请再去看一下DFD图是什么,否则应该看不懂下文。 TLB填充,TLB查询是你必做的动作,因为它就是这个功能本身的定义。无论你把这个功能放在软件里面做,还是硬件里面做,你总是得做的。拿这个TLB填充为例,你要软件做,接口可以定义软件必须在发出VA前填充TLB,否则硬件停机或者异常。又或者让硬件查表的时候给软件发中断,要求它填。你要硬件做,可以让软件一开始就把整个页表放在内存中,TLB查询不到的时候,由硬件的某个部件来做这个填充。硬件还可以进行局部预估,每次加载一个TLB项的时候,根据机器学习得到某种Pattern,自动加载另外一些项进来,提前做好准备。你还可以软硬结合,把填充历史反馈给软件,让软件给出一组Hint,告诉你下次预装载哪些项…… 所以其实接口这个东西,本身会产生数据流。我们通常不在DFD中放接口本身产生的数据流,因为DFD并非一个设计逻辑分析模型,而是一个需求分析模型。我们是通过DFD描述核心的“数据加工”需求是什么,然后决定如何分配里面的每个“加工”步骤,决定是哪个模块来负责。对于架构师来说,他其实在某种程度上不怎么在乎这个加工放在哪一边,因为放哪一边都是工作量。 插一句:其实,这还是个自由度的问题。如果你只有软件团队,而且平台都是买的,你能控制的就一两个模块,你的加工都得放在你可控的模块里,你可想的东西就会少很多,第三方的能做的,你只能让它做,不能做的,你只能自己做。所以其实限制越多,设计难度越低。就好像有人说的:最容易解决的问题就是钱的问题——要不有钱,要不没钱,不用多想。 但那个模块的负责人,就不是这样看了。 所以,复杂系统的架构师,经常在这种问题上碰到困难。模块之间,都希望拿好做,容易出成绩的加工放自己一边;把坑多,不好出成绩的加工放到别人的模块里。不过这个算是小问题了,大部分时候就是个利益的问题,分配好利益就好了。 其实更难的问题是:这个接口怎么定?因为每个模块都在问:你对我是什么要求?你严格定义好了,我一定给你实现出来。 但两个模块,到底应该A模块定义接口呢?还是B模块定义接口呢?我遇到的情况,大部分时候是都不想定义这个接口,一方面这个工作量巨大,出了任何错(接口部分信息传递不过去),都是妥妥的锅;另一方面,这通常是个吃力不讨好的工作,因为“加工”本身不是接口实现的,到时吹牛说某某特性是你做的,接口是最难吹的。 但接口定义决定了整个系统的性能,它才是整个架构工作的核心。一种方法当然是架构团队做,但架构团队根据什么做呢?这是个递归问题:你没有深入设计两边的模块,你就不知道这个接口怎么才是高效的。但你不定义这个接口呢,两边的模块无法深入设计。 更大的问题是,架构团队又不是神仙,我工作二十多年了,和各种团队和大拿共事过,交流过,从来没有见过真正的通才。不说别的,同时懂软件和芯片细节的专家我就没有见过。你凭什么设计这个接口? 你说你用中断通知软件破坏流水线,转头芯片设计团队就来告诉你这不会,因为人家分支预测能预判这种情况。你说你芯片可以根据虚拟机ID转发中断,转头Hypervisor团队告诉你,这用不上,因为按人家的流程,都是先在安全区收集所有的中断,判断过权限以后才重新分发出去的。你找谁说理去? 关键是,就算你是多领域的通才,这还是个细节问题,如果你把细节问题都解决了,你还要其他设计团队吗?你自己就都把设计都做了。我们定义接口,把某个加工放到接口的这一边还是那一边,判断条件是主要是: 这个加工需要的数据主要在哪一边接口上是否有足够的带宽和实时性提供加工需要的数据流程需要的驱动力是否可以插入某侧的驱动框架中(比如某一侧本来就有一个线程定期监控数据,那么就不需要另一侧主动创建中断来通知另一边)某个加工是否可以和某侧已有的加工简单结合 这些都需要知道两边的细节设计才能做出合理判断。我举个最简单的例子,就事论事讨论这里的接口,你能想到在TLB表中加上ASID?你不做微内核这类频繁IPC的系统,你根本不可能想到要加ASID吧? 所以,接口定义这件事情,我们必须建立一个基本的认识:我们不可能一次到位的。它就是一个先做一部分关键功能,尽量不建立太多约束(留下余地),然后开始设计两边模块的内部,然后再升级调整,然后再进一步设计,然后在细化两边的模块设计。每次升级,都有可能对原来的定义产生一定的破坏(这考验定义时留余地的功夫)。这样小心翼翼做下去,我们最终可能可以拿到一个挺好的接口。而指望把责任推给任何一个模块或者团队,然后觉得自己没有错,花大量的时间希望接口一次成型,最终它就成不了型。 这又是某种意义上的“无名”。你问“有什么方法完成一个接口定义”?答案是没有。但你认为“那么接口就没法定义了?”,回答是“不是”。这个事情可以做,但它“无名”,你不要指望“精确定义它”,然后把它变成生产线行为。这个世界的主体就是“无名”(没有Pattern的)。
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/21840.html