计算机的体系结构是关于计算机自身的系统架构,而软件指令集架构在计算机体系结构中处于核心地位,因为软件和硬件之间都是通过软件指令集架构(ISA)来对话的。
例如,在20世纪60年代早期,IBM 有四个不兼容的计算机系列,面向小企业、大企业、科学和实时处理的市场细分,每个系列都有自己的 ISA、软件栈和 I/O 系统。能否创建一个单一的 ISA来有效地统一起来呢?数据路径是处理器的“肌肉”,执行算术运算,相对容易拓展,最大挑战是处理器的扩展。受到软件编程的启发,莫里斯 · 威尔克斯提出了简化控制的方法。控制器被指定为一个二维数组,称之为“控制存储区”,数组的每一列对应一条控制线,每一行对应一条微指令,写微指令的过程称为微程序设计。控制存储器是通过内存实现的,这比逻辑门的成本要低得多。在微程序设计的帮助下,IBM 新的 ISA 彻底改变计算机行业,并主导了它的市场,以至于几十年前的大型机家族现在仍然每年带来百亿美元以上的收入。
这是架构创新的成功,也往往需要大量的工程投资。
从集成电路到8086
当计算机开始使用集成电路时,摩尔定律意味着控制存储可能会变得更大,反过来允许更复杂的 ISA。微处理器在20世纪70年代仍然处于8位时代(如英特尔8080) ,主要用汇编语言编程,竞争对手通过汇编语言的例子来展示他们的优势。
英特尔的8800 ISA 是一个雄心勃勃的计算机架构项目,它具有基于32位能力的寻址、面向对象的体系结构、可变位长度的指令,以及用当时新的编程语言 Ada 编写的操作系统。然而,英特尔在1979年紧急更换16位微处理器,新团队用52周的时间来开发新的“8086”ISA,设计并制造芯片。由于时间紧迫,设计 ISA 只有10个人/周,主要是将8080的8位寄存器和指令集扩展到16位,这个团队按计划完成了8086。IBM 正在开发一种个人电脑来与苹果 II 竞争,并且需要一个16位微处理器。IBM 感兴趣的是摩托罗拉68000,但它落后于 IBM 的开发计划,转而使用了8086。后来IBM PC大卖,为英特尔 的8086 ISA带来了一个非常光明的未来。
最初的8800项目在1986年停止使用,那一年英特尔在80386中将16位8086 ISA 扩展到32位,其寄存器也从16位扩展到32位,x86的 ISA 成功了,因为市场是很少有耐心的。
从复杂指令集到精简指令集
20世纪80年代早期,业界对大型控制存储器的复杂指令集计算机(CISC)进行了多项研究。随着 Unix 操作系统使用高级语言编写,关键问题就变成了: “编译器会生成什么指令?”,硬件/软件界面的显著提升为架构创新创造了机会。
如果编译器只使用简单的寄存器操作和加载/存储数据传输,避免了更复杂的指令, 使用简单指令子集的程序运行速度要快三倍。这样的实验和向高级语言的转变导致了从 CISC 转向 RISC 的机会。首先,简化了 RISC 指令,因此不需要微代码解释器。RISC 指令通常像微指令一样简单,可以直接由硬件执行。其次,原来用于 CISC ISA 微码解释器的存储器被重新用作 RISC 指令的缓存。第三,基于图形着色方案的寄存器分配器使编译器更容易有效地使用寄存器。最后,可以在单个芯片中包括一个完整的32位数据通路,以及指令和数据缓存。在类似的技术中,CISC 每个指令周期执行了5到6个时钟,而 RISC 的速度大约提高了4倍。
接下来的 ISA 创新是显式并行指令集,在每条指令中捆绑多个独立的操作。如果一条指令可以指定,编译器技术可以有效地将操作分配到多个指令槽中,硬件就可以变得更简单。与 RISC 方法一样,将工作从硬件转移到了编译器。但基于这一思想的64位处理器,虽然在高度结构化的浮点程序中运行良好,但是对于分支较少的整数程序来说,它很难实现高性能。市场最终再次失去了耐心,导致出现了 x86的64位版本。
从PC时代到后PC时代
AMD 和英特尔使用了众多资源和卓越的半导体技术来缩小 x86和 RISC 之间的性能差距。指令解码器再次受到简单指令性能优势的启发,在运行过程中将复杂的 x86指令翻译成类似于 RISC的内部微指令,然后流水线执行 RISC 微指令。任何在 RISC上用于执行/分离指令和数据缓存、芯片上的二级缓存、深层管道以及同时获取并执行多条指令的想法都可以并入 x86,在2011年前后,PC时代差不多到了巅峰时期。
PC软件成为了一个巨大的市场,尽管 Unix 市场的软件供应商会针对不同的商用 ISA 提供不同的软件版本,但 PC 市场只有一个 ISA,所以软件开发商提供的软件只能与 x86 ISA 二进制兼容。庞大的软件规模,相似的性能和更低的价格使得 x86主导了台式计算机和小型服务器市场。
2007年,苹果推出了 iPhone,开启了后PC时代。智能手机公司没有购买微处理器,而是使用其他公司的设计,主要是 ARM 的 RISC 处理器,在芯片上建立自己的系统(SoC)。移动设备设计人员认为芯片大小和能源效率与性能同样重要,这使得 CISC 的 ISA 处于不利地位。此外,物联网的到来极大地增加了处理器的数量以及在芯片尺寸、功耗、成本和性能方面所需的权衡。这种趋势增加了设计时间和成本,进一步使 CISC 处理器处于不利地位。在如今的后 PC 时代,x86的出货量自2011年以来几乎每年下降10% ,而带有 RISC 处理器的芯片则在飙升。如今,99% 的32位和64位处理器是 RISC。
回顾之后,市场解决了 RISC/CISC 的争论, CISC 赢得了 PC 时代的后期阶段,但 RISC 赢得了后 PC 时代。
当从单核时代到多核时代
“如果一个问题没有解决方案,它可能不是一个问题,而是一个不需要解决的事实,而是需要随着时间的推移加以解决。“
自20世纪70年代末以来,选择的技术是基于金属氧化物半导体(MOS)的集成电路,首先是nMOS ,然后是CMOS。MOS 技术的惊人改进速度成为驱动因素,使得有更积极的方法来实现给定 ISA 的性能。由于晶体管密度随着速度线性增长而二次增长,人们使用了更多的晶体管来提高性能。虽然摩尔定律已经持续了几十年 ,但在2000年左右开始放缓,到2018年,摩尔定律的预测与当前能力之间的差距大约为15倍,随着 CMOS 技术接近基本极限,差距将继续扩大。
在1986年到2002年之间,开发平行指令的层级是获得性能的主要结构方法,随着晶体管速度的提高,导致每年性能提高约50% 。为了保持流水线满负荷运行,预测分支投机性地将代码放入流水线以便执行。这种预测的使用既是性能的来源,也是效率低下的原因。当分支预测对的时候,可以提高性能,只需要很少的额外能量,甚至可以节省能量。但是当它“错误预测”分支时,处理器必须丢弃错误推测的指令,这时的计算工作和能量都被浪费了。处理器的内部状态还必须恢复到错误预测分支之前的状态,从而消耗额外的时间和能量。实际上,没有什么程序能够有能够如此精确预测的分支。这导致了多核时代的诞生。
多核技术将确定并行性的责任转移到了程序员和操作系统身上,无法解决能源效率的挑战。无论是否有效地提高了计算效率,每个活跃的内核都在燃烧能量,而且并行计算的加速受限于顺序运算的部分。真正的程序有更复杂的结构,允许在任何时刻使用不同数量的处理器。尽管如此,需要周期性地进行通信和同步,这意味着大多数应用程序都只能有效使用一小部分处理器。此外,多核处理器受到热耗散功率(TDP)或封装和冷却系统的限制。TDP 的限制直接导致了处理器将放慢时钟频率并关闭空闲内核以防止过热。
从通用处理到特定领域
那些掩饰成无法解决的问题是摆在我们面前的惊人机遇。
通用处理器固有的低效率,使得人们不可能在通用处理器中保持显著的性能改进。鉴于提高性能以支持新的软件功能的重要性, 还有哪些方法可能有前途呢?
一种更加以硬件为中心的方法是设计针对特定问题领域的计算机体系结构,并为该领域提供显著的性能提升,因此被称为“特定领域的体系结构”(DSA),这是一类为特定领域可编程的处理器通常是图灵完整的,但是针对特定类别的应用进行了定制。它们不同于特定于应用程序的集成电路(ASIC) ,后者通常用于一个代码很少更改的单一功能。DSA通常称为加速器,数据应用系统可以取得更好的性能,包括图形处理单元(GPU)、用于深度学习的神经网络处理器和用于软件定义网络(SDN)的处理器。
DSA 为特定领域开发了一种更有效的并行形式,可以更有效地利用内存,而内存访问比算术计算成本高得多。通用 CPU 通常支持32位和64位整数和浮点数数据。对于机器学习和图形学中的许多应用来说,这比需要的精确度更高。例如,在DNN中,推理通常使用4位、8位或16位整数,从而提高了数据和计算的吞吐量。同样,对于 DNN 训练应用程序,FP 是有用的,但是32位可能就足够了,16位是通常可以工作的。
DSA需要针对体系结构的高级操作,但是试图从通用语言(如 Python、 Java、 c 等)中提取这种结构和信息是非常困难的。领域特定语言(DSL)支持这个过程,并使高效地编写 DSA 成为可能。例如,DSL 可以使向量、稠密矩阵和稀疏矩阵的操作显式化,从而使 DSL 编译器能够有效地将操作映射到处理器。DSL的例子包括 Matlab、 TensorFlow、 P4(一种用于编写 SDN 程序的语言) ,以及 Halide等。
使用 DSL 时的挑战是如何保持足够的独立性,使用 DSL 编写的软件可以移植到不同的架构,同时实现高效地将软件映射到底层 DSA。例如,将 Tensorflow 转换为使用 Nvidia GPU 或TPU的异构处理器。对于语言设计者、编译器工作者和 DSA 架构师来说,在各个ISA之间平衡可移植性和效率是一个较大的挑战。
上图所示,TPU 与通用处理器完全不同。主要的计算单元是一个矩阵单元,多种技术的结合是多重累加计算大约是通用单核 CPU 的100倍。与缓存不同,TPU 使用24兆字节的本地内存,大约是2015年通用 CPU 的两倍功耗。使用基于 Google 六个常见推理问题的加权算术平均,TPU 比通用 CPU 快29倍。TPU 对于这种工作负载的能量效率比通用CPU 高出80倍以上。
从开放式体系结构到敏捷硬件开发
受到开源软件成功的启发,为了创建一个“ Linux for 处理器”,需要行业标准的开放式 ISA,这样社区就可以创建开源核心。如果许多组织使用相同的 ISA 设计处理器,更大的竞争可能驱动更快的创新。
第一个例子是 RISC-V ,RISC-V 的社区在 RISC-V 基金会的管理下维护着这个架构 http://riscv.org/。开放式的 ISA 演变发生在公开的场合,硬件和软件专家在最终决定之前进行合作。RISC-V 是一个模块化的指令集,一小部分指令运行在开源软件栈上,然后是可选的标准扩展,可以根据需要包含或省略这些扩展,基线版本包括32位和64位的版本。RISC-V 只能通过可选的扩展来增长,;即使不采用新的扩展,软件栈仍然运行良好。RISC-V 的显著特点是 ISA 的简单性,与 ARM 公司开发的 armv8相比,RISC-V 只有很少的指令,以及较少的指令格式。RISC-V的指令格式只有6种,而 armv8至少有14种。由于 RISC-V 的目标范围从数据中心芯片到物联网设备,设计验证可以成为开发成本的一个重要部分。简单性降低了设计处理器和验证硬件正确性的工作量。RISC-V 是一个干净的设计,避免了微架构或技术相关特性,这些特性已经被编译器技术的进步所取代。RISC-V还通过为自定义加速器保留大量操作码空间来支持 DSA。
除了RISC-V,Nvidia 还在2017年宣布推出了一个免费开放的架构,名为NVDLA ,这是一个可扩展的、可配置的 DSA,用于机器学习推理。配置选项包括数据类型(int8、 int16或 fp16)和二维乘法矩阵的大小,ISA、软件栈和实现都是开放的。
再次受到软件开发流程的启发,ECAD工具提高了抽象层次,支持敏捷开发,这种更高层次的抽象增加了设计之间的重用。
上图图概述了敏捷开发方法如何通过在适当的层次上改变原型来工作,最内层是软件模拟器,如果一个模拟器能够满足一个迭代,那么软件模拟器是进行改变最容易和最快捷的地方。下一个级别是FPGA,它可以比一个详细的软件模拟器快几百倍。FPGA可以运行操作系统和类似于SPEC的完整基准,允许对原型进行更精确的评估。AWS在云中提供了FPGA服务,因此可以直接使用而无需首先购买硬件和建立实验室。下一个外层使用 ECAD 工具来生成芯片的布局。即使在工具运行之后,在准备生产新的处理器之前,也需要一些手动步骤来精炼结果。如果目标是制造一个大型芯片,那么最外层的设计是昂贵的。
小结
软件创新可以给计算机体系架构的创新带来启发,提高硬件/软件接口的抽象层为创新提供了机会,市场最终决定了计算机体系结构的争论。摩尔定律的终结不是必须要解决的问题,而是被认识到的事实,特定于领域的语言和体系结构使人们从专有指令集的链条中解放出来。在开源生态系统的帮助下,灵活开发的芯片将展示先进的技术,从而加速商业应用,处理器的 ISA 很可能是 RISC-V,流程也可能演进到敏捷硬件开发中来。