仓库源文

.. Kenneth Lee 版权所有 2021

:Authors: Kenneth Lee :Version: 1.0

机器腔和人类腔

这个文档我们来讨论一个技术标准本文写作中很容易犯的错误。

比如,我们会说:

    | XXX特性可以计算数据报文的校验和。

这是人类腔,或者更确切一点,这是“人类总结腔”,这个东西可以形成一个“恍惚”,我们 大概可以知道它是什么,但要说基于这句话写程序,那是不可能的。这只是一种总结,总 结可以写,但认为写了总结,你就定义了一个标准,这就不对了。

要能写程序,你需要的是“机器腔”,或者更确切一点说,应该叫“机器定义腔”:

    | 当get_capa() & CAPA_XXX为真的时候,XXX特性被使能。当XXX特性被使能的时候,
    | get_xxx_checksum()函数结果有效。get_xxx_checksum()结果有效时,它的功能
    | 如下……

这是可以用于写出程序的。

这是“名可名,非常名”这个游戏的有趣之处。前面这个定义,总结起来,也是“说明XXX特 性的功能”,后面这个总结起来,也是“说明XXX特性的功能”,你和别人交流,要总结性地 说这两件事,说出来的“总结”都是一样的,但你说的不是同一件事。所以,“名”确实“可名 ”,但确实也“非常名”。后面这个叫“坐进此道”。拿着扫把的人才是扫地,总结“扫地”的人 不在扫地。但这个事情本身是个层层递进的关心,后面做这个定义的人,也不是在实现 get_capa这个函数。

但如果我们要“定义”XXX特性的规范,后面这个机器腔,才是我们需要定义的。

    | The basis for the Sv32 family' translation is 4KB base pages.
    | To trun on this feature....

这是一个总结性的定义,是人类腔。我们大概可以猜出4KB base pages是什么意思,但它 并不严格。不能用于层层递进。

    | Sv32 implementation support a 32-bit virtual address space,
    | divide into 4KiB pages. An Sv32 virtual address is partitioned
    | into a virtual page number (VPN)...

这是机器腔,一层层过去的:虚拟地址是32位的,虚拟地址分成VPN,VPN又是巴拉巴拉的 。这严格限定了范围。

还有这样的:

    | 全局变量GLOBAL_XXX_CFG必须设置成非零值。

“必须”,这是人的思维,不“必须”咋地?你打我?

机器不是这样的,机器的思维是:

    | 系统复位后,GLOBAL_XXX_CFG为0。系统预期,在调用任何xxx_前缀的函数前,
    | GLOBAL_XXX_CFG会被设置为非零值,否则这些函数都会抛出异常
    | EXCEPTION_CFG_NOT_SET。

还有这样的:

    | Sv32 is a 3-Level page table.

这是总结,就算它是3级页表又怎么样呢?我程序该怎么写?我程序想知道的是:

    | In Sv32 mode, the virtual address is defined as follow...

里面有两个VPN加一个offset,这就是3级页表,但3级页表是总结,不能用于支持写程序, 你还是要告诉我VA是什么样的。

附录

一些接近的例子

下面这个例子不是机器腔的问题,但仍和进行标准定义有关系,比如:

    | CPU和XXX协处理器是一对一的映射关系。

这是人为总结的思路,我们实现一台机器的时候,确实准备给每个CPU都加上一个XXX写处 理器,但这不是描述机器的思路,因为你不能说我不能在系统中为了特定的目的增加一个 没有XXX协处理器的CPU吧?

所以更接近机器思维的描述是这样的:

    | 每个capa位中有XXX位的CPU,都有独立的XXX协处理器实体与之对应。

这两种表述的主要不同是限制的范围不同。前一种表述限制了系统中所有的CPU,而这种限 制明显是无收益的(你非要制造一个收益我没话说,如果那是你的意图,那就这样定义吧 ),后一个是个明显每点限制,都对准了我们的收益的:我不在乎你有多少CPU,但如果你 声明了你有XXX的capability,你就给我放在XXX协处理器进去。

我们继续沿用这个协处理器(为了讨论方面,我们把它简称做COP)的例子。有人会喜欢这 样的定义:

    | COP定义了32个寄存器,可以被CPU直接访问。

这是人天然的感觉,因为我们就是觉得协处理器和CPU是两个相互独立的实体,协处理器有 32个寄存器,通过CPU的指令\ cop_move eax, cop_r0\ ,这不是不是很自然让CPU去“操 作协处理器了吗?”

但显然这不是机器的感官,机器的感官是,你用\ cop_move exa, cop_r1\ 和普通的 move eax, ebx\ 这两个行为本质上不都是CPU的指令吗?怎么前者就变成CPU去控制写处 理器呢?

所以,正确的说法应该是:

    | COP包含了32个寄存器,可以通过专用的CPU指令进行访问。

这看起来只是个“说法”上的不同,但其实概念空间发展了就会不一样。因为当我们认同了 是\ cop_move\ 是一个CPU的指令,我们也认同了我们对CPU指令的所有假设,比如中断 的时候,\ cop_move\ 是可以被打断的。但如果我们认为cop_move是CPU发给COP的一个 内部指令,那么是否可以打断就要单独说了。正确认清“你我”,是我们正确描述有 “自由度”的“严格设计”的关键。