本文的逻辑原来是在一个讨论中给做硬件的同学解释软件为什么不能根据硬件(注:在本文中,芯片也是硬件)的变化随便修改而建立的,但在讨论中很难把逻辑表达得很规整,所以我在这里整理一下,以便后续使用。
软件之所以叫软件,是因为它比硬件容易修改:硬件的东西,一旦投片了,投板了,就基本上动不了了,多就是飞一下线,或者在封装上做点手脚,能解决的问题非常有限。但软件不同,软件你爱怎么改怎么改,改完重新编译一下(甚至很多软件连编译都不用),就能拿去用,从这个角度来说,软件比硬件软。
但软件又很“硬”,有很多东西软件是改不动的。因为硬件是一个硬件,但软件是一堆的硬件。我们可以从这个事实来理解这句话的含义:很多的硬件开发的方法是把原来的设计拿出来(模型也好,Verilog也行),根据新的需求,修改原来的参数,线路等等东西,就可以做成另一块单板了。这另一块单板或者芯片,和原来的硬件一点关系没有,你改什么都影响不了原来硬件(假设叫A1)吧,你这个新的硬件(假设叫A2)在设计上完全不受A1的限制,你很自由(规则上反而很软),但软件,通常是要同时支持A1和A2的,它可不能随便修改程序,这呈现出来就很硬。你也许辩解说:难道我们不能让A1用一种软件,A2再用另一种软件吗?
啊,你问到关键点了:当然可以,你说的恰恰就是嵌入式软件的特征,嵌入式软件形式上其实做的是硬件。但嵌入式软件不需要“生态”,也就是说,没有其他人给它写软件了,只有这么一个软件,用户用你这个“设备”,就用了你的硬件和这个硬件对应的软件,这确实是可以的,多就是你有些维护成本(比如修改A1的一个Bug,修改完还要找A2也修改一次)。但如果你的设备上,还要运行几千几万中其他人写的软件呢?你让这几千几万的开发者,给你的A1和A2都写一次?你谁啊?何况,发展起来,你不是只有A1和A2,你可能有A1, A2, A3, A4,A4.1, A4.1.2-big-endian,A.1.2-fix-reset-bug……这些硬件版本,你让他们写多少次?你家里的软件团队每次修改Bug修改测试多少次?
软件的硬,在于它是一个软件对应多个硬件,它被旧的硬件的包袱固定住了,你要它修改这些东西,它改不动。你不能不支持这些旧硬件的,因为这些硬件都在客户家里放着呢,你跟他们说你扔了买新的吧,看他们会不会来掐死你?——就算你免费送,客户买的那些旧软件怎么跑?你也给钱?你给钱也不行,还有用户自己写的脚本呢?——这些东西就算你愿意给他们写,人家也没有这些时间陪你调试。
或者你会说,那旧设备就不要升级软件好了。那用户就面对每个硬件要维护一套软件这个需求了,人家不答应。
软件要同时支持多种硬件,它会构成这样一种实现结构:
这个“功能抽象”的代码,抽象了A1, A2……这些硬件的共性。但这个代码一旦写下来,它就变“硬”了,你做了一个A3,修改了不少东西,要求修改这个“功能抽象”中的内容,我们就得在功能抽象中增加一个if this_is_a3的逻辑(我也不管这个逻辑是通过编译态的宏决定的,还是通过运行态的代码逻辑决定的,反正都是一个判断逻辑),这会影响功能抽象的维护难度。特别是如果A1, A2, ... A1000都有这样的东西的时候,这个就不是功能抽象了,这和每个硬件一个版本没有什么区别了。
更重要的是,上面这个图其实只是故事的部分,完整画出来可能是这样的:
你这些if xxx,能不能保证不影响功能抽象对上面这些软件的承诺?
所以你以为功能抽象不过是个软件,你爱怎么改就怎么改。但现实是,广泛的应用范围,绑死了功能抽象的大部分自由度。
对于操作系统基本的功能,这个“上层软件”是个什么概念呢?我们有一个服务器类的部门的数据是:他们要支持的软件大概是10亿行代码这个级别,而且不算分支。
后,说到操作系统,我们再来补充一下“软件生态”这个概念。
有人以为,我做了一个新的芯片,甚至自己弄一个指令集,需要做的工作是使能一个个的软件,等前面说的这10亿行代码的软件都能在我的硬件上跑了,我就“拥有生态”了。
这个目标有点远,但也有个努力的方向,而且很多地方也不见得非要10亿行,还有不少“功能抽象”类的软件,也不需要我们改,这个问题慢慢就能解决。
但事情没有你想得这么爽,大部分主流软件都在以月,周甚至天为单位升级,你觉得你今天“使能”了一个数据库,明天它还能不能在你的硬件上跑,那可不一定。而且,它在一个“分支”上给你使能了你的硬件,在它之上,利用它的各种进步而开发出来的其他软件可都不属于你,你得到的是一个死的数据库,这毫无意义。所谓“生态”,是一个“活着的系统”,你靠一个个使能,这叫得到她的身体,得不到她的心,后都是悲剧收场的。
所以,我们做芯片的同学们,不要以为软件可以成为你作死的后盾,好好做你设计的构架,想好长远发展是啥样的,否则软件的软是救不了你的。
这个世界的自由从来都非常有限,浪漫和自由只存在在童话中,其他的自由,都会被生活和细节教做人,终变成庸俗。