随便说说,关于处理器技术和龙芯之类
作者声明啊:那些大黑体字是版主帮我编辑字体大小的时候加上的,可能是为了方便阅读吧。我本人不太喜欢这种大字报一样的强调,感觉太强势。我本人也没有这种强调让大家接受这些观点的意愿,欢迎大家讨论。呵呵~~
最近上网看了很多骂架,自己忍不住打水文一篇,各位看官就当说笑吧
计算机至今已有六十多年历史,单片集成的微处理器(从 4004 开始)也已有三十多年,这不可能在一片小小的文章里说清楚,当然我也没有这样的能力了解到每一点。主要想给大家一些基本概念,在今天网络上关于龙芯混乱的 “ 自主 ” 和 “ 知识产权 ” 之争中提供一点相关的背景知识。
当然我也很矛盾,因为处理器设计本身是 “ 非平民化 ” 的 技术,要让没有经过专业培养的人看了一篇文章就明白处理器设计是怎么回事,几乎是不可能的事情。再者我水平也有限,我只能说对于不同专业背景的人,大家能 看懂多少看多少,我讲错的地方也欢迎指证。这篇文章最前面的部分,是给非电子计算机专业的人读的。中间部分,需要一定的电子计算机相关基础,非电子计算机 专业的人可以当看看热闹。最后的部分,可能涉及到一些体系结构方面的专业知识。我发贴的目的是纯技术性的,所以我本人不希望卷入非技术性的争端。
关于处理器的历史起源,可以从很多途径中获得,关于那段电子管到集成电路的历史,我就不再提了。其实微处理器的基本结构大部分人在中学计算机课程里面都 学过,就是所谓的冯诺依曼结构。处理器从存储器中逐一取得指令,进行指令所指定的相关操作,这些操作可以是各种算数的和逻辑的操作,完成一条指令的操作后 再取下一条指令,依次进行下去。这里就涉及到一个问题,就是放在内存中的指令是如何向 CPU 表达 CPU 该进行何种操作。按照计算机术语来说,定义一整套处理器所执行的操作及其指令的表达方式,就叫做指令集体系结构( ISA )。
计算机所接受的都是二进制编码,当前主流桌面计算机是 32 位或是 64 位。所谓 32 位机也就是处理器以 32 位作为基本的处理单位,处理器里面的存放数据的寄存器也是以 32 位大小为单位的,指令也是以 32 位为单位。刚提到指令向 CPU 传达的要进行何种操作的命令,也是通过这 32 位为单位进行表达。例如一个普通的加法 A + B = C ,一个 32 位的指令最开始的几位表达的是要进行何种操作,例如这里的加操作,可以用一串二进制数来表示,比如 “100001” 。类似, “100010” 可以表示乘, “100100” 可以表示除,以此类推。接着,指令集要告诉计算机对哪两个数进行加法,对于 RISC 机来说, A 和 B 是预先被取到处理器内部的寄存器里面的。所以后面的指令后面的部分要表示从那个寄存器取,例如 “000001” 表示第一个寄存器, “000010” 表示第二个寄存器。这样, A 和 B 两个数,就需要用两个相应的二进制串来表示,这跟在开始讲的表示何种操作的二进制串后面。最后,还有我们的结果 C ,这也需要由一个二进制串来表示,表示的方式和 A 和 B 是一样的。我们要事先定义这些二进制串的含义,哪几位表示哪种含义,处理器才能明白程序(程序也就是由这些二进制串所构成的,存在内存中等待处理器来读取)想让它做什么。
中科院计算所从 MIPS 公司得到的授权,就是这些二进制串的表达方式。为什么这个如此重要,因为别人已经针对这种表达设计了相关的编译器,设计了相关的软件产品。如果你采用不同的表达方式,你的处理器是无法 “ 看懂 ” 别人的程序的,所以你必须自己设计全套的编译器和配套软件产品,这个工作量不比设计一个处理器来的小。而且,要考虑到市场因素,原来苹果公司用的处理器是非 X86 指令集的,后来迫于市场压力也放弃了 POWERPC 系列转投了 X86 阵营。
作为龙芯处理器来说,要获得市场回报,如果一整套编译器和软件都要从头设计,没有现成的相关支持,这是不现实的。但作为处理器设计来说,定义一套自己的指令集,并不是什么难事。
刚才已经谈到了什么是指令集体系结构,那么有了这样一个对二进制编码的协定,就有 CPU 了?显然不是。 CPU 本身是要你自己设计的。网上很多讨论缺乏最基本的认识,以为从人家地方买了这样一套关于指令集的协定,其它的都不用干了,程序自己就会跑了。同一套指令集,可以有很多不同的实现方式,这些实现的性能也是天差地别的。这里的问题就是我们已经有了一套关于指令的协定告诉 CPU 要做什么样的操作,那么 CPU 本 身是如实现根据这套协定来执行相关的操作,这个概念叫做处理器微体系结构(只是为了好理解这么说,当然正统定义不是这样的)。刚才所说的指令集定义叫做指 令集体系结构,现在这个叫做处理器微体系结构,这两个表达的是不同的含义。中科院计算所所做的工作,也就是龙芯系列处理的设计,主要是后者。一般来说微体 系结构包含逻辑设计的概念,但最终芯片要出来,是要进行物理层面的设计的。计算所的工作,也包括了物理层面的设计,集成电路专业术语,叫做 LAYOUT 。
这些年时常在电子工程师论坛和其它论坛逛,很早就知道很多电子工程师对龙芯有诟病,这也不是从这次签约才有的。从一方面来说,有一句话叫做 “ 难者不会,会者不难 ” ,因为很多人从事过相关的工作,比如 ASIC 或者 SOC 设计,知道这是怎么回事,就会有一种不以为然的态度。不过有另外一个词,叫做 “ 知易行难 ” , 即使大概知道处理器是怎么工作的,不代表就能设计出一个处理器来。处理器这个东西水还是很深的。以飞机作为类比,一架几百块钱的模型机也能上天,一架价值 几亿美元的超音速战斗机也能上天,但两者的技术难度肯定不一样。很多人说在国外设计处理器是本科生的课程,这个不假,国外很多本科有处理器设计相关的课程 设计。但这个就和做一架模型机一样,会做模型,就能说明做飞机只有这个难度? CELL 开发的时候, IBM 、东芝和索尼三个公司投入了数亿美元建立研发中心,有数百个工程师参与,前后花了四年多。如果真这么简单,那 IBM 的老板真是秀逗了。我无意比较龙芯和 CELL ,只是想说不要把处理器设计这件事情看得太简单化。完成龙芯这样一个超标量处理器设计的难度,和课程设计的难度是不一样的。
回到技术主题上,刚才提到了一套指令集可以有不同的微体系结构实现方式。从处理器发展历程来说,最原始最简单的处理器,是多周期处理器。学过数字电路, 知道状态机,原始处理器的处理方式和状态机是一样的。指令是作为这个状态机的输入,然后由状态机控制整个处理器的运作,基本上处理器的运作方式是:首先读 入一条指令,同时更改程序计数器指向下一条要取的指令;然后对读入的指令进行译码;接着从存储器取得操作数;然后 ALU 进行相关操作;最后把结果写回存储器。这是最基本的处理器操作方式,这些过程都是顺序化执行的,有核心状态机统一控制。在几十年前的处理器中,有一种叫做 “ 微码 ” 的东西,存放在处理器内部的 ROM 里面,一条一条的读出由 “ 微码 ” 来控制整个处理器的运作,作用和状态机是一样的。微码又分横向和纵向的,不过这些都是比较久远的故事,就不再多阐述。
在多周期 CPU 之后,大概是在八十年代中期,所有学计算机体系结构的人都不会不知道两个人,就是 JOHN HENNESSY 和 DAVID PATTERSON 。这两位体系结构领域的巨匠是 RISC 机的发明人(不过至于谁发明 RSIC 机这个问题,在 VLIW 发明人 JOHN FISHER 的著作《 EMBEDDED COMPUTING 》里面还有一段论述,题外话呵呵)。其中第一位 JOHN HENNESSY 现在是 STANFORD 大学的校长,也是今天因为龙芯被很多中国人熟知的 MIPS 公司的创始人。 RISC 的核心思想,主要就是规整化的指令集结构,所有指令集有统一的格式,例如 MIPS 只有三种格式的指令。另外,包括高速缓存( CACHE )和流水线也是当年 RISC 机区别于 CISC 的主要标志,但在现今几乎所有处理器都有 CACHE 和流水线。
处理发展的下一个阶段,就是标量流水线处理器。刚才说的那些取值,译码,执行,回写等步骤,在标量流水线处理器中被重叠。这个概念,和福特车的流水线生 产概念是一样的,每个工人只完成当前自己的步骤,然后马上抛给下一个工人。看过卓别林的《摩登时代》,大概就知道流水线啥意思。数据就像在传送带上的零 件,然后每个工人只负责自己的一部分,中间不停歇的送给下一个工人。在处理器里面也是类似,每个模块之负责自己的一部分,取值的只负责取值,译码的只负责 译码,执行的只负责执行。但这里最理想的情况,有不理想的情况出现,就是跳转指令,和中断的发生。具体的解释可以去看 JOHN HENNESSY 和 DAVID PATERSON 的经典著作《计算机组成与设计,软 / 硬件接口》,懂的人觉得我罗嗦,不懂的人看我说了也不懂,所以我还是就此打住吧。
简单的标量处理器的问题在于,无论这些跳转和中断处理得再完美,处理器的最高性能只能是一个周期一个指令。因此在下一个阶段,目标是超过一个周期执行一个指令的限制,让一个周期可以同时执行多条指令。一个非常有名的缩写,叫做 ILP ( INSTRUCTION LEVEL PARALLELISM ),即指令级并行,虽然说流水线处理器也是典型的 ILP 处理器,但更多的 ILP 处理器指的是每个周期可以同时执行两条及两条以上指令的处理器。也就是我们说的多发射处理器。基本的多发射处理器有两种类型,第一种叫做非常长指令处理器(中文是这样么?真难听啊,英文叫 VERY LONG INSTRUCTION WORD ,即 VLIW ),另一种叫超标量处理器( SUPERSCALAR ),其实还有叫做超级流水的,但不盛行,就不介绍了。龙芯二代,属于超标量处理器,设计为每个周期内四条指令可以同时开始执行,因此叫做四发射超标量处理器。
VLIW 和超标量的区别,主要在于 VLIW 是依赖于编译器静态处理器指令相关性的技术,而超标量是由硬件动态处理器指令相关性的。 VLIW 的优势在于简化了硬件,因此应用主要在功耗和面积为主要约束的嵌入式场合,例如 TI 的 C64X 系列的 DSP 处理器就是采用 VLIW 体系结构。在桌面系统中,现在只有 INTEL 的安腾是类似 VLIW 的处理器,但相比而言它是介于 VLIW 和超标量之间,叫做 EPIC 处理器。国防科大好像有做类似的处理器结构。整个桌面处理器市场,现在几乎是超标量处理器独占的。
虽然说超标量处理器是标量 RISC 处 理器的下一代发展,但在实现难度上是上了一大级。从物理层面上行,要支持多条指令同时执行,所有的寄存器就要支持多条指令同时取数据,同时写入数据,而且 寄存器和执行部件之间需要有复杂的链接网络,支持寄存器的数据分配到每一个执行部件上。为了支持动态的指令调度,还需要加入保留站,为了防止伪数据依赖, 需要寄存器重新命名技术,另外为了保证程序的顺序性语义,还需要将原本乱序执行的指令重新排序。还有内存访问的相关操作,也有相关性和维护存储器一致性的 问题。我只能大概提一下这些问题,如果说你在学习这方面的知识, H&P 的另一本书《 computer architecture: a quantitative approach 》很好的解释了核心算法,但我的看法是它对具体实现的结构论述不足。 CMU 的《 modern processor design 》提供了一个比较好的实现结构的教程,其实我个人最推荐的书是《 advanced computer architectures, a design space approach 》,不过这本书国内有没有引进版我就不清楚了,这本书提供了一个非常好完整的 survey work ,对整个超标量相关技术做了很好的分类。缺点是这本书稍微旧了一些,但绝对不影响他的论述。
第一个商用单片集成超标量处理器可能是 AMD 的 AM29K 系列,是根据设计者的博士论文设计的(抱歉原来说的是 K5 , K5 是 AM29K 的后续产品)。不过 IBM 的早期试验机 AMERICA 也是超标量处理器。现在的龙头老大 INTEL 并不是最先(不过 i960 也很早,不是学历史的就不纠结这些谁第一了), INTEL 有名的 P6 结构从体系结构意义上来说,也并不能说是那个年代最完善的结构。 P6 采用集总式的保留站,把重命名和重定序放在一起(如果我没记错的话)。但市场么并不单全由性能单方面决定。产业链等问题,其实远比纯技术性能本身来得重要。当年 SPEC 性能最高的 ALPHA 系列,也随着 DEC 的消亡走向末路,卖到康柏,后来又转到惠普,微软放弃了对 ALPHA 系列的支持也是它最终消亡的原因。这也是龙芯为什么不能自立门户单干,用自己的指令集,而需要取得 MIPS 兼容的目的之一。因为我不是龙芯的内部人员,具体的东西我也没法得知,但从龙芯组发表的论文来看,龙芯的微体系结构,和 MIPS 公司九十年代后期的产品 R10000 有些类似。当时 MIPS 处在巅峰时期, MIPS 处理器是用在 SGI 的超级计算机上的。但后来 SGI 还是撇掉了 MIPS , MIPS 就退出了桌面处理器市场,只有在嵌入式领域应用。龙芯可能会让 MIPS 又重新回到了桌面市场(如果成功的话呵呵)。
前面说的是龙芯二代用的超标量结构,当前处理器的时代,可以用 “ 走向多核 ” 来形容。大家都知道龙芯三是多核处理器,很多人说多核性能好,其实也是一种无奈的做法。有一个名词叫做 DIMINISHING RETURNS ,意思就是再多的投入,不能获得相应的回报。单处理器发展遇到的瓶颈,包括本身功耗的问题(限制的频率,现在感觉 IBM 的 POWER 还在继续飙主频, 5G 以上, INTEL 从 P4 到 CORE DUE 主频都开始往下降了,这个大家都知道),存储器访问速度的问题,指令发射窗口大小的限制,错误推测和 CACHE MISS 的 PENALTY (抱歉我不知道中文该怎么翻译才好)等,导致了 ILP PROCESSOR 的性能不能在继续提升。再者,包括逻辑设计和验证的复杂性问题等,这些都迫使处理器不得不往多核的方向走。像体系结构界的泰斗 YALE PATT 多次说多核是一种不高效利用硅片的方式,不过当时好像是个辩论, IBM 的工程师说,那你让我们怎么办,硅片用不完,除了放核放 L2 CACHE ,你还能让我们怎么整。但多核也不能说是就把所有问题都交给软件去做,硬件就只需要简单累加单核处理器。比如互联结构的带宽,存储器一致性( memory consistent ), CACHE 一致性( cache coherence ,发现中文分不清楚这两个词,都叫一致性,不过含义还是稍有不同的),这些都是需要从硬件角度来解决的问题。大家都知道最新的 INTEL 和 AMD 多核处理器都是不用 FSB 了, INTEL 的技术叫做 QPI , AMD 的叫 HT ,都是基于 PACKET 的网络式通信方式。早些我一直觉得 NOC 的研究把东西弄得花哨但不实用,但现在看来,随着 MANYCORE 的这种趋势, NOC 的研究还会继续热下去。
回到龙芯三上来,先前很多很多人,一会说龙芯三仿 STANFORD 的 IMAGINE ,一会说仿 IBM 的 CELL ,我也不知道到底仿的什么东西。不过最近看到 IEEE MICRO 上面龙芯自己发的 PAPER ,觉得和 IMAGINE 和 CELL 扯不上什么关系,做的是 CC-NUMA 的结构, IMAGINE 和 CELL 都被定义为 STREAM ARCHITECTURE ,主要特征在存储器结构,管理方式和编程模型。但从龙芯三上,我没看出这种特征。我不太清楚最初的传言模仿这个模仿那个是怎么开始的。
前面说了很多体系结构的问题,其实光有所谓的体系结构,还是远远不够的。很多论文里面用 SIMPLESCALAR 做一个 SIMULATION ,就可以把 SIMULATION 的结果拿出去发。但作为一块真实出产的芯片,这还差得远的远。除了体系结构的问题外,还要完成集成电路设计的整套工程流程。很多人贬龙芯的理由,比如抄袭 R10K 的结构之类。真要做龙芯这样一个芯片,整个工作的工程量是非常大的。 SUN 的一个工程师,有一本不太厚的著作叫做《 CPU DESIGN, ANSWER TO FREQUENCY ASKED QUESTION 》,这里面几乎把超标量处理器主要的结构和各个模块之间的细节都比较完善的给出来了。但做整个 C/C++ MODEL ,到 RTL 代码,时序分析功能验证, POST SIMULATION , LAYOUT ,流片等等,不可能是知道体系结构是怎么样,芯片自己就出来了。这些工作是需要投入很大人力去做的。
在 INTEL ,做一片 CACHE 都需要投入几十个人。很多人对 INTEL 的看法就是神,只要 INTEL 想做什么,投入做什么,其它公司都不用混了。例如网络处理器, INTEL 买了 ARM 核,弄了很多人在马来西亚搞了很多年,但始终无法摆脱 ARM 核的束缚,现在把整块都卖掉了。包括千呼万唤屎不出来的 LRB ,水木 CSARCH 上说只要 INTEL 愿意去做 GPU ,那 NVIDIA 和 AMD 都不用混了。其实现实是 INTEL 确实搞了很多人去做 LRB ,但实验性能还不如 NVIDIA 。说这些, INTEL 不是神话的企业, INTEL 里面的工程师也是肉做的人。龙芯也一样,并不是说 INTEL 牛逼,龙芯就一定只有死路一条。
打了一大篇水文,因为最近在网上看到很多纯 “ 骂文 ” 。总的来说,身为一个技术人员虽然我也不喜欢 HWW 那 套政治大论,但在中国这样一个社会环境里面,有些东西也没办法。我个人还是很支持龙芯的发展,要说经费之类,其实相比于国外,我们的科研经费确实不算是很 充裕。不要老说什么国内科研环境之类之类,一切东西都是要钱的,国内国外都一样。龙芯这样一个重大意义的项目,国家多支持一点,多投入一点也是应该的。
相对于我这样的在网上发发水文的,中科院计算所已经为国家做了很多了。但有一点,我觉得更应该做的是加强我们教育,龙芯的技术真的做的不错的,但光靠那 些人弄,我们还是没办法达到整体水平的发展。其实我倒觉得别非要总是想着这么产业化,其实很多技术到现在根本不是什么绝密技术,用不着整天搞什么产权保 护。自己有了这些技术,用于教育更多的学生,让更多的人能进入这个领域,或许才是国家真正的发展大计。