雷锋网 (公众号:雷锋网) 按:近几年来,不论是普通消费者还是科研人员们都可以感受到两种浪潮,一种是 CPU 速度的提升越来越不显著了,我们说 CPU 制造商又在「挤牙膏」;另一方面,在深度学习的刺激下,各个半导体巨头和一群 AI 初创企业都开始宣传自己的 AI 芯片。我们仿佛看到一类芯片逐渐走向慢车道,另一类芯片则准备搭台唱戏、跃跃欲试。
这种柳暗花明的背后,显示的正是计算机计算架构的时代变革;新的方法、新的思维、新的目标引领了新的浪潮。2017 年图灵奖的两位得主 John L. Hennessy 和 David A. Patterson 就是这个新浪潮的见证者和引领者。近日他们在 ACM 通讯(Communications of the ACM)发表了一篇长报告,详细描述了引发计算机架构新时代到来的种种变化,他们也展望未来的十年将是计算机体系架构领域的「新的黄金十年」。
雷锋网把这篇文章全文编译如下。本篇为下篇,上篇见这里。
另外二位还有过一次轻松的访谈,可以点击这里。
ISCA 2018 ,2017 图灵奖颁奖现场,John L. Hennessy(左) 和 David A. Patterson(右)与 Alan Turing 的半身像合影
「我们面前有一些令人目瞪口呆的机会,不过它们把自己伪装成了看似无法解决的困难」。 -John Gardner
不论是对于 ILP 的技术或者多核心处理器,由于为通用计算设计的微处理器注定了效率较低,再加上Dennard Scaling定律和摩尔定律走向终结,所以在我们看来,处理器架构师和设计师们很有可能再也无法让通用处理器的性能以之前那样的速度继续大幅提高。但是我们仍然需要想办法继续提升硬件性能、为未来的新的软件功能留下发展空间,我们就必须仔细思考这个问题:有没有其他的有潜力的方案?
比较明显的方案有两种,以及把这两种方案合并在一起的话我们还可以得到第三种方案。
第一种方案是,现代软件的编写中大量使用了高级语言,其中有动态类型和动态存储管理。然而不幸的是,这些语言的编译和执行是非常低效的。Leiserson 等人用矩阵乘法的小例子说明了这种低效性。
Python 是一种当前火热的编程语言,也是一种典型的高级、动态类型语言。如下面图 7,仅仅是把本来用 Python 编写的程序用 C 语言重新写一遍,就可以把程序的性能提高 47 倍。在多核心处理器上并行运行多个循环可以继续得到大约 7 倍的性能提升。优化程序的存储布局,让程序使用处理器中的缓存(而不是外部安装的内存)可以提升 20 倍性能,最后,如果加入拓展的计算硬件,用能够在每个指令周期内计算 16 次 32 位运算的单指令多数据并行(SIMD)计算单元进行运算的话,我们还可以再把性能提高9倍。把以上这些改进全部用起来的话,
一个运行在英特尔多核处理器上的、经过高度优化过的程序可以比最初的 Python 版本快超过 6 万倍。
这当然只是一个很小的例子,一般的程序员可能自己就会使用一个有优化作用的库来享受这种提升。虽然这个例子把性能的变化展现得很夸张,但是在许许多多的程序中,提升 100 倍或者 1000 倍的性能还是完全可以实现的。
有一个有趣的研究方向是,考虑其中的一些性能差距是否可以用更好的编译器技术来补上,当然了也可以同时搭配一些计算架构的改进。虽然高效的语言翻译、以及高效实现 Python 这类的高级脚本语言确实有很大困难,但潜在的性能收益也是巨大的。即便我们只实现了这些潜力中的 25% 就已经可以让 Python 程序的运行速度提高数十倍甚至一百倍。这个简单的例子就清晰地展示了关注软件工程师的生产力的现代编程语言和关注程序性能表现的传统方法之间的巨大鸿沟。
设计专用硬件
领域专用的计算架构。除了改进软件执行效率的第一种方案之外,第二种方案更加以硬件为中心,那就是为某个特定的领域问题设计专用的计算架构,从而为这些问题带来显著的性能(和效率)提升。这种方案的名字,DSA,「domain-specific architectures」,描述的就是这种为特定的领域问题而专门定制设计的处理器,它们可编程,同样也是图灵完备的,但只适用于特定的某一类问题。从这个角度来讲,它们和专用集成电路 ASIC 之间也有所不同,ASIC 只执行单一的功能,对应的程序代码几乎从不变化。DSA 则常被称为加速器,相比于把程序的所有功能都在为通用计算的 CPU 上执行,DSA 可以让程序中的一部分计算运行得更快。更重要的是,DSA 可以让一些程序得到明显更高的性能,因为它们就是为了贴近这些程序的计算需求而设计的。图像处理单元 GPU、深度学习中使用的神经网络芯片、软件定义网络处理器 SDN 都是典型的例子。DSA 可以达到高得多的性能表现和高得多的能量效率,是由于以下四个原因:
第一点,也是最重要的一点,DSA 可以为具体的领域问题采用更为高效的并行计算设计。比如,单指令多数据并行(SIMD)就比多指令多数据并行(MIMD)的效率高得多,因为它只需要获取一条指令流就可以让处理单元在锁定步骤内执行运算。SIMD 的灵活性固然不如 MIMD 高,但是它很符合许多 DSA 的需求。DSA 中还有可能使用 VLIW 方案来实现 ILP,而不是使用更复杂的乱序执行机制。正如前面提到的,VLIW 无力与通用计算代码竞争,但是在有限制条件的领域中它就可以高效得多,因为它的控制机制简单得多。尤其是,多数的高端通用计算处理器都是乱序执行的超标量处理器,对于指令初始化和指令完成都需要复杂的控制逻辑。相比之下,VLIW 在编译的时候就已经执行好了必需的分析和流程规划,在显示并行的程序中就可以起到很好的效果。
第二,DSA 可以更高效地利用不同层次的存储器。Horowitz 指出,读写存储器的成本已经变得高于数学运算的成本了。比如,从一个 32KB 容量的缓存里读取一个块需要消耗的能量差不多要比执行一次 32 位整型加法高 200 倍。正因为这种差别的存在,想要达到高的能源效率,优化存储器的读写就至关重要。通用计算处理器执行代码的方式是,一般来说存储器的读写都具有时间和空间上的局部性,但是其他状况是在程序编译时很难预测的。所以 CPU 会配合使用多级缓存,以便增加存储器带宽,同时缓解相对较慢的片外存储(内存,DRAM)的高延迟问题。CPU 消耗的电能里,常常有一半都是花在了这些多级缓存上面,不过它们的作用也就是避免了大多数对片外 DRAM 的访问,要知道,读写 DRAM 消耗的能源要比读写最后一级缓存还要高差不多 10 倍。
缓存的缺点会在这两种情况下暴露出来:
当数据集非常大的时候,缓存的时间和空间局部性都很差;
当缓存表现得非常好的时候,也就是说局部性非常高的时候,这其实说明大多数缓存都是空闲的。
在那些存储器的读写模式有良好定义、在编译时就可以发现的应用中(典型的 DSL 都符合),程序员和程序的编译器都可以优化存储器的使用,效果要比动态分配缓存更好。所以 DSA 通常会使用一个层次式的存储器,它的操作也是由软件明确定义的,这和向量处理器的运行方式很类似。对于适合的应用,用户控制的存储器消耗的能源要比缓存低多了。
第三,在适当的时候,DSA 可以用更低的精度做运算。通用计算 CPU 一般支持 32 位和 64 位整型以及浮点数据运算。不过对于机器学习和图形领域的许多应用来说,这样的精度都高于实际需求了。比如在深度神经网络中,推理任务经常使用 4 位、8 位或者 16 位的整型,以获取更高的数据吞吐量、更高的计算吞吐量。类似地,在深度神经网络的训练中需要使用浮点类型,32 位就已经够用了,16 位很多时候都可以。
第四,如果程序是用领域专用语言(DSL)编写的,由于语言本身对并行化有更好的支持,DSA 也就可以从中受益。这改进了存储器读取的结构和表示,也可以更容易地把应用程序映射到一个领域专用的处理器上去。
DSA 需要把编程语言中的高级操作对应到硬件架构上去,但是想要从 Python、Java、C、Fortan 这样的为通用型计算设计的语言中提取这样的结构和信息实在是太难了。领域专用语言(DSL)让这个过程变得可以实现,而且也让我们有机会高效地为 DSA 编程。比如,DSL 中可以定义显式的向量、稠密矩阵、稀疏矩阵操作,这样 DSL 的编译器就可以高效地把这些操作映射到处理器中。许多语言属于 DSL,比如矩阵运算语言 Matlab,深度神经网络编程用的数据流语言 TensorFlow,DSN 编程语言 P4,以及描述图像处理中高级变换操作的 Halide。
使用 DSL 的时候也有一个挑战,就是如何让硬件架构设计保持足够的独立性,这样在一种 DSL 中编写的软件可以迁移到不同的硬件架构,同时在把软件映射到下方的 DSA 的时候还能过保持足够高的效率。比如,TensorFlow 中的 XLA 系统可以把编写的程序翻译成使用不同处理器的版本,在英伟达 GPU 和谷歌 TPU 上都可以运行。在 DSA 之间平衡可迁移性的同时还要保持足够高的效率,这对语言设计师、编译器设计师、DSA 架构师们来说都是一个有意思的科研挑战。
下面用 TPUv1 这款 DSA 芯片举例做详细的解释。谷歌 TPUv1 的设计目标是加速神经网络的推理过程。这款 TPU 从 2015 年就投入了生产环境开始使用,它支持着谷歌的各种应用计算需求,包括搜索查询、语言翻译、图像识别,一直到 DeepMind 的围棋/象棋 AI AlphaGo/AlphaZero。这个芯片的设计目标就是把深度神经网络推理时的性能表现和能量效率提升 10 倍。
如下方图 8 所示,TPU 的内核结构设计和通用计算处理器完全不同。其中的主计算单元是一个矩阵计算单元,这是一个脉动列表结构,它可以在每个时钟周期进行一次 256x256 矩阵的乘法加法运算。在这项功能上联合使用的 8 位精度、高效率的脉动架构、SIMD 控制、专门划分出的一大片芯片面积,最终让这个乘法累加器的每时钟周期性能比一般的单核心通用计算 CPU 提升了大约 100 倍。而且,TPU 中并没有使用缓存,它使用的是大小为 24MB 的本地存储器,这相当于是 2015 年时期的相同功耗的 CPU 上带有的缓存空间的 2 倍。最后,激活值存储器和权重存储器(以及保留权重的 FIFO 架构)都通过一个用户控制的高带宽存储通道连接在一起。在基于谷歌数据中心的六种常见推理问题的加权性能统计中,TPU 要比通用计算 CPU 快 29 倍。由于 TPU 消耗的电能还不到 CPU 的一半,在处理这些负载时 TPU 的能量效率要比通用计算 CPU 高 80 倍还不止。
总结
我们分析了通过提高硬件效率来提升程序运行性能的两种不同的方案。方案一,改进通常是解释执行的现代高级编程语言的性能;方案二,设计领域专用的计算架构,相比于通用计算 CPU 的表现,这样可以极大改进运行速度和能源效率。DSL 也是改进硬件/软件接口,从而让计算架构设计师们可以做出 DSA 这样的创新的另一个重要例子。
想要通过这些方式取得程序性能的显著提高,需要一支垂直集成的设计团队,他们需要了解应用、了解领域专用语言以及对应的编译器技术、了解计算机架构和组件,并且了解其中蕴含的实现技术。在整个计算机产业链变得水平整合之前,计算领域的许多早期工作都表现出了强烈的「垂直集成、可以跨越多个不同的抽象层次」的特点。而在现在这个新时代中,垂直整合能力变得更为重要,能够做出重要的权衡并进行检验和优化的团队将会占有先机。
这些改进机会已经引发了计算架构创新的新浪潮,吸引了许多来自不同计算架构设计逻辑的竞争者:
GPU - 英伟达 GPU 有许多核心,每个都有很大的寄存器,有许多硬件线程,也有缓存
TPU - 谷歌 TPU 主要依赖其中的大规模二维脉动乘法累加器,以及依靠软件控制片上存储
FPGA - 微软在数据中心中部署了现场可编程逻辑阵列(FPGA),这些数据中心是专为神经网络应用优化的
CPU - 英特尔提供的 CPU 带有许多核心,然后用大容量的多级别缓存和一维 SIMD 指令增强 CPU 的性能;英特尔也提供微软使用的 FPGA,以及另一种更接近 TPU 的新型神经网络处理器。
除了这些大体量的竞争者之外,也有好几十家初创企业提出了自己的想法。为了满足不断增长的计算需求,计算架构设计师们把这样的芯片成百上千地互相连接起来,形成了为神经网络计算服务的超级计算机。
深度神经网络的瀑布式结构也为计算机架构设计带来一段有趣的时光。很难预测 2019 年中这些不同的方向中是否会出现胜利者,但是市场最终一定会为这场竞争分出胜负,就像它过去也曾分出了一场计算机架构之争的胜负一样。
受到开源软件的成功的启发,计算机架构的第二个发展机遇在于开放 ISA。为了创建一个「处理器的 Linux」,这个领域需要工业标准级别的开放 ISA,这样整个生态中才可以创建开源的核心,在不同公司持有各自的专有核心架构的环境中形成补充。如果许多组织结构都使用同样的 ISA 设计处理器,更激烈的竞争可能会带来的更快的创新和发展。这里的发展目标是为不同的使用用途提供不同规模的处理器设计,可以有 100 美元一个的处理器,也可以有几美分一个的处理器。
这里的第一个例子就是 RISC-V,UC 伯克利大学开发的第五代 RISC 架构。在 RISC-V 基金会的管理之下,RISC-V 有一整个生态维护着这个架构。选择了开放,也就让这个 ISA 也可以在公众中露面,软件和硬件专家们也可以在做出最终决定之前就展开合作。开放体系还会带来一个好处,就是 ISA 很少会出于纯市场营销的原因而扩大,相比之下专有指令集就经常会为了市场营销而增扩充指令集。
首先,RISC-V 是一个模块化的指令集。一小组基础指令首先支持整个开源软件框架的运行,然后有一些标准的拓展指令,设计师们可以根据自己的需求添加或者删除。基础指令含有 32 位和 64 位地址的版本。RISC-V 指令集的增长完全可以只依靠可选的拓展指令的增加,支持软件框架运行的基础指令不增加任何新的拓展也不会有任何问题。专有指令集的处理器架构一般都会需要向前的二进制兼容性,这意味着如果一家处理器制造商决定在某一代处理器中增加一个新的功能,那么这家制造商未来的所有处理器都需要保留对这个功能的支持。但 RISC-V 就不需要这样,所有的功能增强都是可选的,而且如果没有应用需要的话就可以随时删除。目前 RISC-V 中有如下几个标准的拓展指令集,用首字母作为它们的简称
M. 整型乘法/除法
A. 原子内存操作
F/D. 单精度/双精度浮点运算
C. 压缩指令
其次,RISC-V 有一个特色是 ISA 的简洁性。下面提供了一组 RISC-V 与 ARM 公司在近似时间开发的 ARMv8 架构的对比,虽然对比的内容不是完全可以量化的。
指令更少。RISC-V 的指令更少,基础指令只有 50 条,这个数量和这些指令的性质和最初的 RISC-I 惊人地相似。其它的几个标准拓展指令集,M、A、F 和 D,一共增加 53 条指令,再加上 C 的另外 34 条,一共也只有 137 条。ARMv8 则有超过 500 条。
指令格式更少。RISC-V 的指令格式更少,只有 6 种,而 ARMv8 至少有 14 种。
第三,RISC-V 的简洁性不仅降低了设计处理器的复杂度,也减小了验证硬件正确性的难度。由于 RISC-V 的目标就是要应用在包括数据库的高性能计算芯片到 IoT 设备上的低功耗芯片上,设计验证也可以在开发成本中占据不小的比例。
第四,RISC-V 是一个完全从头开始的设计,它是在初始设计的 25 年后开始的。它的设计师们从前几代的设计中吸取了许多错误经验。与第一代的 RISC 架构不同,RISC-V 避开了依赖微架构和依赖技术的特征(比如延迟分支和延迟载入)以及很新的创新(比如寄存器窗口),实际上这些功能都随着编译器技术的发展而被替代了。
最后,RISC-V 还可以为定制化设计的加速器提供很大的操作指令设计空间,这为 DSA 提供了良好的支持。
除了 RISC-V 之外,英伟达也在 2017 年发布了一个免费开放的架构,名为英伟达深度学习加速器(NVDLA),这是一个用于深度学习推理的标量、可配置的 DSA。它的可选配置包括数据类型(8 位整型、16 位整型、16 位浮点)以及其中的二维乘法矩阵的大小。根据不同的配置,芯片面积可以有 0.5mm2 到 3mm2 的不同大小,功耗也有 20mW 到 200mW 不同。这个架构的 ISA、软件架构、实现方案也都是全部开放的。
开放的简单架构实际上会带来安全方面的好处。首先,安全专家们并不相信模糊不清就可以带来安全,所以开放的技术实现方案对他们更有吸引力;开放的技术实现也就需要开放的架构。同等重要的是,有越来越多的人和组织机构参与,也就可以围绕安全的架构设计做出更多改进。专用的架构把参与者局限为企业的员工,而开放的架构允许全世界学术和工业界的人参与提高安全性。更重要的是,这样开放的架构、技术实现、软件架构,再加上 FPGA 的高可塑性,都意味着架构设计师们可以在线部署并评价新的解决方案,而且这个周期不再是以年计,而是以周计。虽然 FPGA 比定制化芯片慢大约 10 倍,但这样的性能表现也已经足以支持用户的在线使用,也就可以针对真正的攻击者更及时地做出安全改进。我们期待开放的计算架构未来成为架构设计师和安全专家们进行软硬件联合设计的典型范例。
Beck 等人撰写的《软件敏捷开发手册》为软件开发领域带来了一场革命,它克服了传统瀑布式开发中精心设计的开发计划和文档经常失效的问题。小的编程团队得以快速开发出包含了核心功能但并不完善的软件原型,然后在下一次迭代开始前就获得用户反馈。竞争性的敏捷开发可以让 5 到 10 人的开发团队以 2 到 4 周一次迭代的速度快速前进。
再一次,受到软件开发领域成功经验的启发,硬件领域的第三个机遇就是敏捷硬件开发。对架构设计师们来说也有一个好消息,现代电子计算机辅助设计(ECAD)工具提高了抽象级别,可以让敏捷开发以及对应的更高级别的抽象在不同的设计之间重复使用。
如果说要把软件开发中的每四周一次迭代的快速前进方式照搬到硬件开发,一听之下会觉得难以置信,毕竟从硬件设计定版到得到芯片成品就有好几个月的时间。而下面的图 9 就展示了敏捷开发过程中可以在适当的抽象级别上更改原型。最中央的抽象级别是软件模拟器,也是在迭代中做改动最简单、最快的部分。下一层是可以比细致的软件模拟器运行快数百倍的 FPGA。在 FPGA 上可以运行操作系统,也可以进行全功能的性能评测,比如 SPEC 中的测试项目;这让原型的评价更加准确。亚马逊云服务就提供了 FPGA,架构设计师们无需购买 FPGA 硬件并建立实验室就可以使用 FPGA 做自己的验证。为了获得芯片面积和功耗的具体数值,下一层的 ECAD 工具可以生成芯片的布局图。在工具运行完毕之后还需要人工进行一些步骤,对结果进行微调,确保新的处理器已经准备好投入生产了。处理器设计师们把这下一层称作「tape in」。前面的这四个级别都可以使用每四周一次的迭代速度。
如果是出于科研目的,我们在 tape in 这一步就可以停下来了,因为这时就已经可以获得非常准确的面积、能耗、性能的估计数据了。不过如果真的停下来的话,那就像参加长跑比赛,最后在重点线前 50 米停了下来,「因为可以准确地预测出最终要花多少时间了」。既然已经在比赛的准备以及前面的大部分赛程中投入了许多精力,但只要不冲过终点线,那就没办法享受到真正的兴奋和满足。所以其实,硬件工程师在有个方面比软件工程师强,就是因为他们最终会生产出切实可感的物品。把芯片成品拿回来测量、运行真正的程序、把芯片展示给他们的朋友和家人们看,这都是硬件设计工作中非常幸福的时刻。
许多研究人员会认为他们需要在芯片试产之前停下来,因为芯片的制造实在是太贵了。实际上,当芯片很小的时候,它的制造价格就非常便宜。架构设计师们委托半导体厂商制造 100 个 1mm2 面积的芯片只需要花 1.4 万美元。如果是以 28nm 工艺制作,1mm2 的面积上就可以放下数百万个晶体管,足以容纳一个 RISC-V 处理器再加一个英伟达加速器。如果要制造一个很大的芯片,那么最外面这一步可能就会花很多钱,但是如果是为了展现新的想法的话,小的芯片就可以做到。
「黎明之前正是最灰暗的时刻」-Thomas Fuller
要从历史经验中学习,有几件事架构师们必须知道:软件开发领域的创新点子同样可以启发硬件架构设计师们,提升硬件/软件接口设计的抽象级别可以为创新带来机会,以及市场最终会为计算机架构之争画上句号。iAPX-432 和 Itanium 的故事说明了硬件架构方面的投资可能无法带来对等的回报,而 S/360、8086、ARM 架构则能够年复一年地带来充沛的盈利。
Dennard Scaling 定律和摩尔定律走向终结,以及标准微处理器的性能提升越来越慢并不是什么必须解决不可的问题,而实际上,它们完全可以看作是令人激动的新机遇。高级别、领域专用的语言和架构把架构设计师们从专用指令集不断扩充的链条中解放出来,同样也释放了公众对于更高的安全性的需求,这都会带来计算机架构的新的黄金时代。另外依靠开源生态的帮助,敏捷开发的芯片也会越来越令人信服地展现出它的优势,并逐步越来越快地取得商业上的成功。对于通用处理器的设计理念,ISA 未来也将随着时间的流逝而越发显得熠熠生辉,就像 RISC 一样。在新的黄金时代中我们可以期待继续看到上个黄金时代那样的高速发展,只不过这次首当其冲的是价格、能耗以及安全,性能当然也会有继续的提高。
在未来 10 年中,我们可以期待在计算机架构领域也看到寒武纪生物大爆炸那样地充满新鲜创意,这对于学术界和工业界的计算机架构设计师们来说会是一段充满激情的时光。
via acm.org ,雷锋网 AI 科技评论编译
雷锋网原创文章,未经授权禁止转载。详情见 转载须知 。