在那个年代所采用的一种主要方法就是实现针对HLL的处理器,就是把一个中间ISA裁剪为一种HLL,然后,采用或开发类似的处理器硬件以通过微编程来仿效经定义的ISA。在上世纪50年代,微码首次被剑桥大学在EDSAC项目中由Maurice Wilkes实现,人们初开发它是为计算机控制逻辑而开发一种更为简单的方法1。微码由实现中间ISA的基本处理器指 令序列组成。它或者由一些简化的中间语言进行编译,或者以汇编形式进行手工编写。微汇编程序然后把汇编代码转换为可执行代码,这些可执行代码然后被存储在片上本地存储器或快速访问、低延迟存储器上。在上世纪70年代和80年代,设计工程师把微码存储在由分立存储器芯片或存储器模块实现的外部存储器上。在当今的IC集成水平上,处理器微码几乎总是存储在片上RAM或ROM之上。
微码尽管曾经获得了普及应用,但是,本质上已经从现代的处理器设计消失了,因为片上可用硬件快速增加、硬件成本的关联下降以及广泛的采用逻辑综合来进行芯片设计。所有这些发展使得ISA的直接硬件实现更加容易并且更加在经济上有吸引力。
赞成采用微码的案例
微码提供的若干优点:
·目标码在一个家族之内与其它处理器兼容或与以前一代的处理器兼容;
—以各种价格-性能特性能够创建一个家族的待构建的处理器。在该家族中的高端处理器实现中间ISA更为直接或者甚至通过多功能单元而加速它,以开发指令级并行化(ILP)。在该家族中的低端处理器把中间ISA映射至更为有限的硬件上,从而使得程序的执行更慢但是也成本更低。
—在一个处理器家族中,能够在多个处理器上把经编写的编译器用于中间ISA。从中间ISA至较低端机器的实际指令组的映射—具体包括在微码中—可以独立的层编写,并可能避免采用编译器,或者至少需 要非常简单的编译器。进一步说,这样的映射可能很少采用,因为中间ISA不会暴露给用户,并且不必按照HLL可能演化的那种方式演化。一些语言编译器目前采用中间语言形式(例如Pascal的P代码或Java的虚拟机)以及一个两步—或通过解释或两步编译—的过程以产生终的可执行代码;这个过程可以简化 对接并也能够支持针对同一ISA的多个语言—即使不涉及微码。
通过采用多个ISA和多个微码组,由微码编写的处理器能够在运行时间上动态地适应不同的HLL,从而能够针对以不同的语言编写的程序实现更好的执行性能。
对于依赖于解释器的各种语言,对适当的中间ISA的形式开发以及把那个中间ISA的微码映射至目标ISA,能够通过把它们的开发分为更加简单 的两级(对于工程设计来说是一流的划分和征服方法)而加快语言的可用性。如上所述,这可能对于在RISC上实现多语言支持也是一个策略,或者,对于把一个语言对接至多个处理器也是一个策略。
正如上面所讨论的,通过把实现一个语言编译器的过程分为两级,就有可能为一种新的目标机提供语言支持,较之于编写特殊的目标编译器更加快。
利用一个中间ISA指令而不是两个或两个以上的目标ISA指令,代码长度可以被减少。此外,通过从主存储器减少指令抓取的数量可能改善性能。在这种情形下,中间ISA可能较之于固有的机器RISC ISA而创建一种CISC。
对ISA仅仅部分支持而不是全部支持,可能简化一种语言不常用部分的编译器的编写。对于支持ISA的新型处理器的硬件设计也可能在复杂性、设计努力以及项目风险上被减少,因此,采用经过很好测试的微码实现的执行来实现某些功能,可能较之于直接硬件实现来说是更好的替代方法。
这一技术如果利用更多的现代处理技术的优点可能会更好且时钟速率更快,以提供对较老机器以及在更新的处理器上的指令集—对较老的ISA的一种虚拟化—的后向兼容性。下一步就是在软件上完全执行这个转换,而完全不涉及任何微码,这就需要各种技术改善以提供所需要的性能。这样的改善可能包括较高频率、逻辑、可能的多核以及更多的嵌入式存储器。
反对采用微码的案例
微码还具有若干缺点:
与具有较为简单的ISA的机器相比,低端中间ISA机器的性能常常非常差,因为中间ISA机器的分层常常证明并不是化地使用计算资源。
与针对真实的目标机器能够实现的根本简单的ISA的编译器相比,在中间ISA上生成代码的编译器无法做到同一程度的化。对编译的化只能在两个独立的层面上完成。瞄准一个家族中直接实现中间ISA的高端处理器的HLL编译器无法为该家族中的低端处理器进行化,除非为它们做特别的修改,这样会打消它们的一些优点。
为了满足若干不同的语言的要求,一种针对若干不同ISA的机器可能结合不稳定的设计折中,从而为所有的目标语言提供差的性能。
微码编译器、翻译器或生成器(把固定的中间ISA翻译为根本的目标、简单的ISA)可能极度简单或者难以适应,因为它并不打算频繁地运行。此外,微码可能难以改变,特别是如果被存储在ROM之中的话(当然一些机器在片上RAM存储的部分微码允许改变)。
中间ISA概念的一些的支持者把它们具体表达在Burroughs处理器中 (如上所述),但是,在文献中可以发现许多其它的努力,由多年来构建的许多不同的微可编程计算机的可用性来支持。Carlson2讨论的一种微编程 Fortran计算机代表了Fortran语言的接近直接实现,并且仅仅需要一个简单的翻译器,此外,他还讨论了一种微编程的EULER处理器(EULER是Algol 60的变种)。Hassitt、Lageschulte和Lyon3讨论的APL机器就采用了微编程。
在上世纪80年代,Flynn4调查了许多架构方法,其中,包括微码概念,并试图定义直接执行HLL的理想的语言机器。Moulton5研究了 支持HLL编译和执行的微编程及其的一般设计。在用微编程支持的许多其它HLL当中(见前一节更多的讨论)有LISP6和Prolog7。可能说明这一概 念的早代表就是Burroughs机器的B1700/1800系列,它支持面向Cobol、Fortran和RPG8的中间ISA。近,我们已经看到这一方法的元素被用于解释方法之中,如具有P代码的Pascal和具有其虚拟机的Java;尽管具有足够的动机来改善性能并且经过足够的时间,但是,这些 语言的固有编译器仍然会出现。在任何情况下,这些方法可能不必要采用在现代处理器上的微码。
过去残留下来的概念
你可能会推想,上世纪80年代VLSI的出现已经缩减了微编程。的确,行业标准微处理器ISA的出现,那些ISA的多个世代的实现,以及利用现代IC制造工艺可用纯晶体管数的增加,似乎已经减少了微码方法的应用。然而,这一技术的几个发育不全的残迹已经在近几年浮出表面。例如,在上世纪80年代末,Unisys推出了所谓的单芯片A系列主机处理器(SCAMP)9,其中结合的相对低端的RISC处理器类似于该公司在小型、低端的A3和A4主机上采用的处理器,它里面采用的几百K微码就是沿用从上世纪50年代以来在初的B5000出现时所采用的Burroughs "E-model"指令集。SCAMP被用于"Micro-A"计算机,在此,SCAMP芯片利用许多微码ROM芯片被汇编至2英寸×2英寸的多芯片模块之中。
这一方法的另一个有趣的遗迹以及这一问题的一个反例就是在从AMD K610开始的、现在的奔腾级处理器之中发现的问题。在这些处理器中,以前x86处理器世代的CISC指令利用RISC指令集实现。处理器的指令解码单元把CISC指令分解为RISC操作,然后,汇编并把这些更为简单的操作按组流出至处理器的并行执行单元。它并不是严格的微码,但是,它在一定程度上明显从微码而来。
这种设计方法还减轻了为更新的处理器创建新的CISC指令。它创建了一种混合CISC/RISC架构。显然,微架构/微码机器仍然具有一定的作用和位置,它随着半导体技术和处理器架构的不断演化而兴衰。或许,这一蜥蜴类家族树的遗迹将在当今更为敏捷的哺乳类机器上延续下去。
尽管依然存在一些中间ISA的残留应用,如上所述,微码已经证明在进化上走入了死胡同,因为它不如直接用硬件高效地执行一个ISA。一旦硬件电路丰富,微码的硬件效率就会由它的执行低效而超越。在当今的处理器设计中,让大量比较简单的机器通过微码仿效更为复杂的机器显然应用不广泛,尽管存在偶然的例外。新的编程语言常常初通过比较简单的中间表示法进行解释,但是,如果该语言普及并且如果性能成问题,那么,不可避免地会出现针对“裸金属”处理器的有效的编译器,因此,仍然需要采用微编程。