CPU架构原理科普向:ISA
公司面试的时候,我遇到过一个比较有趣的问题是:你要设计cpu,你怎么向你奶奶解释你现在的工作。其实,这是一个非常有趣的问题,为什么面试的时候会经常问?因为cpu设计行业里面,很多专业的知识,别说一般市民,即使是公司里面的其他员工,随时是跨领域的对话,所以,必须会用比较简单的例子来解释复杂的问题。我当时回答是用厨房煮菜的过程来解释cpu的流水线。
那么开始吧。什么是isa?
isa, instruction set architecture. 中文就是,指令,集合,架构。在计算机里面,什么是isa呢?就是xx定义的一个指令集,这里的xx可以指任何东西。比如你只会做加法,你就定义一个叫加法isa,这个指令集只做加法。任何一个isa对于另外一个isa都没有根本意义上的“先进”,isa之间的对比是非常复杂的。你只会做加法,我只会做乘法,你说我们谁先进?我见得比较多的是争吵x86 isa比arm isa先进的,我往往一脸懵逼,好像他们比我懂,我是不是不应该插一腿进去...
x86 isa现在是Intel和AMD共同拥有,也就是说如果你要开新的x86cpu公司你必须向这两者付版权费用,而且必须两者都同意你才能获得完整的isa,如果你只获得一部分不完整的isa,那就和完全没拿到isa一样。ISA在cpu里面,就像是字典,用厨房的比喻就是菜谱,菜谱定义了你这个厨房会做什么菜,这个菜做出来是什么样什么味道,那么顾客在这家连锁店的任何一间都能叫到相同的菜,吃到相同的味道。
ARM isa 当然是ARM公司所有的,当时ARM公司是定菜单的,并且给出试菜的人,说你们每家店都要做出这个味才算ARM。而做店的则是不同的公司,像qualcomn啦,他们中间喜欢怎么做菜是他们的自由,但是必须会那几道菜,必须做出这个味。
x86的良好生态环境是因为他的ISA一直有legacy支持。legacy直接翻译就是遗产。x86的legacy支持的意思就是,世界上第一个x86cpu支持的东西,今年你发明的x86 cpu也支持,以后的也要支持。的确从某个角度上来说,农企和Intel都非常努力的去支持很多已经没什么人的东西,就是餐馆里菜谱里面有些菜基本上你都不会去试的。你说你都不用了,农企Intel还在那里浪费设计是吧?你不用不代表没人用啊,X国很多军用的设备还是Windows95啊,甚至还是服役中的Windows3.1啊,银行的atm还有用Windows98的。别问我为什么他们要那样,如果他们肯花钱找些软件工程师重新写那些程序,就可以用最新的东西,很多没有注释,现在没有人学的语言,或者算法诡异的程序,很多军事设备还在用啊。原因大概是:这种语言连学都没人学,我自己都看不懂,我看你怎么破解我的坦克系统!
但是实际上x86又不是完全100%legacy支持的,至少isa上面没有这样定义,农企和Intel也没有官方明文定义。x86里面有一个指令叫cpuid,系统/编译器运行它的时候,它会给出一些数据,就是告诉系统/编译器,这个cpu支持什么东西,这个cpu有些什么新东西之类的。所以,理论上可以设计一个cpu,不支持那些非常少用的指令,以降低cpu的设计复杂程度,也更省电省事。
那么代码是怎样运行的呢?给纯来看科普的读者的厨房比喻,你要组织一个宴会,然后你说了要弄些什么,你就是软件。然后有个人,专门根据你你要求,弄成一份菜单,他就是编译器。然后把这份菜单给厨房,基本上就是:读菜单拿食材(instruction fetch),切菜(decode),煮菜(execute),上盘出餐(load store and writeback)。然后前面就一读菜单,后面就一直工作。
有时候会听到cpu流水线,如果按照上面的做法,没一个指令都要通过这几部来预算,那么只有一部分电子器件在用的时候,其他部分都在发呆浪费电。就像是,厨房里面,从取菜到上盘全部都一个人做,肯定要累死那个人,但是你炒菜的时候,是不是想,如果有人已经帮你切好菜,我就一直炒菜好了,这样我们厨房工作效率就高了,cpu也是这样。
这是一个经典的cpu运行流水线。换成厨房理论,就是,一个人专门去食材,一个人专门切菜,一个人专门炒菜,一个人专门上盘,一个人专门给客人下单上菜,是不是现代化很多呢!
然而这样不能满足我们cpu的工程师,我们还有branch prediction,什么叫branch prediction呢?程序里面最耗时间的一个就是branch,就像c里面的if,你得到答案之前不知道是继续往下走还是进去if里面的括号。就像下单的小哥,那些犹豫不决而改菜单的人最讨厌了。于是cpu里面有了这个东西,他是怎么用的呢。下单的小哥也不是笨蛋,顾客a来了100多次了,有80次都改单把猪肉改成鸡肉,那么他下单时候,小哥就先说了,改鸡肉,如果顾客a觉得还是猪肉吧,就再抄,如果顾客a真的改单,那么厨房以及开始做了,而且有80%的几率啊,小哥还是挺聪明的吧。cpu也大概是这样,根据每个loop的地址(顾客)来训练出一个未卜先知的系统。
上图里面还有OOO(out of order),例如同一个register,你两个pipeline stage要用同一个相互依赖的register的场景是非常常见的。为了解决这个问题,就有了out of order execute, in order commit。就是不按顺序来运行指令,但是按顺序完成指令。
用厨房理论解释就是,有这么一道菜(或者说两道菜),鸡要先煮了然后炸,你煮熟鸡之前不能炸,否则炸了再煮,口感就不同了,顾客肯定骂死你,但是后面又有其他菜在等,锅你是有的,所以在煮鸡的时候,你先做后面的菜,然后鸡煮好了,再炸。出餐的时候,你还是先出了这道鸡肉再出后的菜,那样顾客就不会投诉出餐的顺序不按菜单了。
原网址:https://zhuanlan.zhihu.com/p/20731557
作者:虞己某
CPU Design Engineer