7.2 DSA 的设计原则
下面五条原则,大体上指导了 7.4–7.7 节将介绍的六种 DSA 的设计。它们不仅提高了面积效率和能效,还带来两个有价值的额外效果。首先,它们使设计更简单,从而降低 DSA 的 NRE(见 7.11 节中的相关谬误讨论)。1 其次,在 DSA 常见的面向用户的应用中,遵循这些原则的加速器,比传统处理器那些性能随时间变化的优化机制,更容易满足第 99 百分位响应时间的截止要求;7.10 节将讨论这一点。图 7.2 概括了六种 DSA 如何遵循这些原则。
1. 使用专用存储器,尽量缩短数据移动距离
通用微处理器中的多级缓存,要消耗大量面积和能量,力求为程序找到最佳的数据移动方式。例如,一个两路组相联缓存的能耗,是等效的软件控制 scratchpad 存储器的 2.5 倍。2 从定义上说,DSA 的编译器开发者和程序员了解目标领域,因此无需硬件代他们尝试安排数据移动。相反,应通过由软件控制、针对领域内特定功能专门设计的存储器来减少数据移动。
2. 把省去高级微体系结构优化所节约的资源,投入更多算术单元或更大的存储器
如 7.1 节所述,设计者曾把 Moore 定律带来的充裕资源,用于 CPU 和 GPU 上资源开销很大的优化:乱序执行、多线程、多处理、预取、地址合并等。对于范围更窄的专用领域,我们对实际运行的程序有更深入的了解,因此,把这些资源用于更多处理单元或更大的片上存储器,往往更为划算。
3. 采用与目标领域相匹配、最容易使用的并行形式
DSA 的目标领域几乎总是具有内在并行性。关键的设计决策是:如何利用这种并行性,又如何把它暴露给软件。应围绕目标领域自然的并行粒度设计 DSA,并在编程模型中以简单方式提供这种并行性。例如,对数据级并行性而言,如果 SIMD 能满足领域需求,那么,对程序员和编译器开发者来说,它肯定比 MIMD 更容易使用。
同样,如果超长指令字(Very Long Instruction Word,VLIW)能够表达该领域的指令级并行性,那么,与推测性乱序执行相比,这种设计可以更小,也更节能。此外,VLIW 和 SIMD 都能提高每次指令访问所对应的计算量。
4. 把数据宽度和类型缩减到领域所需的最简单形式
后文将看到,许多领域的应用通常受存储系统限制。因此,使用更窄的数据类型,可以提高有效存储带宽和片上存储器的利用率。更窄、更简单的数据类型,还能使相同芯片面积容纳更多算术单元,并降低算术运算的能耗。
5. 使用领域专用编程语言为 DSA 编写程序
如 7.1 节所述,DSA 的一个经典难题,是让应用能在新体系结构上运行。一个由来已久的谬误是:假定新计算机足够有吸引力,程序员就会专门为它重写代码。幸运的是,早在设计者被迫转向 DSA 之前,领域专用编程语言和库就已经逐渐普及。例如,DNN 领域的 JAX、PyTorch、TensorFlow(Paszke et al., 2019;Abadi et al., 2016),以及数据库系统使用的 SQL。这些工具大大提高了把应用移植到 DSA 上的可行性。如前所述,在一些领域中,只有应用里规模很小、计算密集的部分需要运行在 DSA 上,这也简化了移植工作。
| 原则 | Google TPUv4 lite | Google TPUv4 | NVIDIA A100 | NVIDIA T4 | Graphcore IPU Bow | Samsung NPUv2 |
|---|---|---|---|---|---|---|
| 目标领域 | DNN 推理 | DNN 训练与推理 | DNN 训练与推理 | DNN 推理 | DNN 训练与推理 | DNN 推理 |
| 设计目标 | 数据中心 ASIC | 数据中心 ASIC | 数据中心 ASIC | 数据中心 ASIC | 数据中心 ASIC | PMD SOC |
| 1. 专用存储器 | 16 MiB VMEM,128 MiB CMEM | 32 MiB VMEM,128 MiB CMEM | 27 MiB 多线程寄存器堆,40 MiB L2 缓存 | 10 MiB 多线程寄存器堆,18 MiB L2 缓存 | 897 MiB 处理器内存储器 | 2 MiB 紧耦合存储器 |
| 2. 更多算术单元 | 65,536 个乘加单元 | 131,072 个乘加单元 | 110,592 个乘加单元 | 20,480 个乘加单元 | 94,208 个乘加单元 | 8192 个乘加单元 |
| 3. 容易使用的并行形式 | 单线程、VLIW、SIMD、顺序执行 | 单线程、VLIW、SIMD、顺序执行 | 多线程、SIMD | 多线程、SIMD | 多线程、SIMD | 单线程、SIMD |
| 4. 更小的数据宽度 | 8 位整数、bf16 | 8 位整数、bf16 | 1 位、4 位、8 位整数,fp16、bf16、tf32 | 4 位、8 位整数,fp16 | fp16 | 4 位、8 位、16 位整数,fp16 |
| 5. 领域专用语言 | JAX、PyTorch、TensorFlow | JAX、PyTorch、TensorFlow | JAX、PyTorch、TensorFlow | JAX、PyTorch、TensorFlow | JAX、PyTorch、TensorFlow | TensorFlow、TensorFlow Lite |
任何能够训练的芯片,也都能够执行推理。与各自的训练版本相比,Google 和 NVIDIA 都通过减少核心数量、降低外部存储器成本,来降低推理产品的成本。
DSA 带来了许多新术语,主要来自新的应用领域,也有一些来自传统处理器中没有出现过的新体系结构机制。与第 4 章的做法一样,图 7.3 列出新缩写、术语及简短解释,便于读者查阅。
| 类别 | 术语 | 缩写 | 简要解释 |
|---|---|---|---|
| 通用 | 领域专用体系结构(Domain-specific architectures) | DSA | 为特定领域设计的专用处理器;领域之外的处理工作依靠其他处理器完成。 |
| 通用 | IP 模块(Intellectual property block) | IP | 可以集成到 SOC 中的可复用设计模块。由此形成了一个市场:一些组织提供 IP 模块,另一些组织将这些模块组合成 SOC。 |
| 通用 | 片上系统(System on a chip) | SOC | 把一台计算机的全部组成部分集成到一颗芯片中;常见于 PMD。 |
| 深度神经网络 | 激活值(Activation) | — | 人工神经元被“激活”的结果,即非线性函数的输出。 |
| 深度神经网络 | 批(Batch) | — | 一起处理的一组数据集,以降低读取权重的成本。 |
| 深度神经网络 | 卷积神经网络(Convolutional neural network) | CNN | 对前一层输出中空间相邻的区域进行加权和非线性运算的 DNN。 |
| 深度神经网络 | 深度神经网络(Deep neural network) | DNN | 由多层人工神经元组成的网络;神经元对前一层输出与权重的乘积应用非线性函数。 |
| 深度神经网络 | 推理(Inference) | — | DNN 的生产使用阶段,也称 serving。 |
| 深度神经网络 | 多层感知机(MultiLayer perceptron) | MLP | 对前一层所有输出进行加权和非线性运算的 DNN;这样的层称为全连接层。 |
| 深度神经网络 | 整流线性单元(Rectified linear unit) | ReLU | 执行 的非线性函数;其他常用非线性函数包括 sigmoid 和双曲正切函数(tanh)。 |
| 深度神经网络 | 循环神经网络(Recurrent neural network) | RNN | 输入同时来自前一层和先前状态的 DNN。 |
| 深度神经网络 | 训练(Training) | — | DNN 的开发阶段,也称学习(learning)。 |
| 深度神经网络 | Transformer | — | 利用注意力机制为输入序列中各位置提供上下文的 DNN。与 RNN 一样,它常用于自然语言翻译和文本摘要;但与 RNN 不同,它一次处理整个输入,而非依次处理。因此,各项运算能够并行进行,使其可以处理大得多的数据。 |
| 深度神经网络 | 权重(Weights) | — | 训练过程中学得、随后应用于输入的数值,也称参数(parameters)。 |
| 深度神经网络 | 大语言模型(Large Language Model) | LLM | 原表也称其为 Frontier models;基于 Transformer 模型的解码阶段,通常拥有数十亿到数万亿个参数。 |
许多领域已经有了 DSA,例如面向图形的 GPU;还有一些领域值得继续探索,包括数据分析、图像处理、安全和隐私。不过,本章贯穿始终的示例是人工智能。