内存计算技术:架构、分类与应用
1. 引言
传统计算机设计将存储和计算的角色分开,由内存存储数据,处理器进行计算。然而,人类大脑并未如此明确地区分两者,这引发了思考:计算机是否有必要维持这种区分?在探讨这个问题之前,我们先来了解一下著名的内存墙问题。
1.1 内存墙问题
内存墙最初指的是快速处理器和慢速内存之间速度差距不断扩大的问题。在过去三十年中,芯片上的处理器核心数量稳步增加,而内存延迟相对保持不变。这导致了所谓的内存墙,即内存带宽和内存能耗开始主导计算带宽和能耗。随着数据密集型应用的出现,这个问题进一步加剧。如今,大量的能量被用于在内存和计算单元之间来回移动数据。
为了克服内存墙问题,架构师们尝试了各种策略,其中大部分集中在利用局部性和构建更深的内存层次结构上。
1.2 计算与内存融合的思路
另一种思路是将计算靠近内存,使计算和内存之间的界限变得模糊。这种方法的关键是将计算单元和内存单元物理上靠近,以此来突破内存墙。它有多种形式,从将计算单元放置在内存银行附近,到更令人兴奋的技术,即消除内存和计算单元之间的界限。
将计算和内存融合有两个主要好处:一是消除了数据移动,从而显著提高了能源效率和性能;二是利用了当今计算平台中超过 90% 的硅片仅用于存储和数据检索这一事实,通过重新利用这些区域进行计算,可以实现大规模并行计算处理。
1.3 早期处理内存(PIM)的尝试
早期在该领域的工作是将离散的计算单元放置在主内存(DRAM)中,这种方法通常被称为处理内存(PIM)。研究人员在 20 世纪 90 年代就讨论过 PIM(最初的建议可以追溯到 20 世纪 70 年代),但当时这个想法并未成功,原因是在 DRAM 芯片内集成计算单元的成本很高,以及由于摩尔定律和登纳德缩放定律,仍然可以进行更便宜的优化。
1.4 3D 芯片堆叠技术推动 PIM 发展
2010 年代初,商业上可行的 3D 芯片堆叠技术(如美光的混合内存立方体 HMC)的出现,重新激发了人们对 PIM 的兴趣。HMC 将 DRAM 内存层堆叠在逻辑层之上,逻辑层中的计算单元可以通过高带宽的硅通孔与内存通信。3D 集成技术允许将采用不同工艺技术实现的计算和 DRAM 芯片堆叠在一起,3D PIM 的额外维度使得计算单元和内存单元之间的物理连接数量增加了一个数量级,从而为计算单元提供了巨大的内存带宽。
1.5 内存重新用于计算的主流技术
近年来,将内存重新用于计算已成为主流技术。例如,美光的自动机处理器(AP)将 DRAM 结构转换为非确定性有限自动机(NFA)计算单元。NFA 处理分为状态匹配和状态转换两个阶段,AP 巧妙地重新利用 DRAM 阵列解码逻辑来实现状态匹配,数百个内存阵列可以并行执行状态匹配,状态匹配逻辑与自定义互连相结合以实现状态转换。使用 AP 可以一次性处理多达 1053 个正则表达式,其效率比 GPU 高一个数量级,比通用多核 CPU 高近两个数量级。
另一条研究路线表明,可以重新利用 SRAM 阵列位线和感测放大器对存储在 SRAM 中的数据进行原位计算。数据存储在共享位线和信号感测装置(感测放大器)的内存阵列中,通过这些共享结构可以进行逻辑运算,从而将数千个缓存内存阵列转变为超过一百万个位串行算术逻辑单元,使现有缓存变成大规模向量计算单元,提供比当代 GPU 高几个数量级的并行性。这种位线计算方式可能适用于多种内存技术(DRAM、RRAM、STT - MRAM 和闪存),并且模拟计算的程度可以调整,形成了多样化的设计空间。
2. 技术基础与分类
2.1 近内存计算与内存内计算的区别
近内存计算和内存内计算这两个术语有时会被混淆使用。下面将对各种近内存和内存内计算方法进行分类,并比较每类内存驱动方法的显著特征。
2.1.1 处理内存与近内存计算
近内存计算是指在靠近内存的逻辑中进行计算。近内存计算架构最初被称为处理内存(PIM),其主要目标是打破内存墙。自 20 世纪 90 年代以来(最初的建议可追溯到 20 世纪 70 年代),PIM 作为克服冯·诺依曼架构内存带宽限制的一种替代方法,吸引了研究人员的关注。其关键思想是将计算单元放置在主内存(DRAM)中,使计算和内存单元紧密耦合。
传统的 PIM 方法在将计算单元集成到 DRAM 芯片中面临一些关键挑战。然而,自 2010 年代以来,商业上可用的 3D 堆叠内存的出现,重新激发了人们对 PIM 的兴趣。例如,美光的混合内存立方体(HMC)在 DRAM 层堆栈下方集成了一个逻辑层,表明可以在逻辑层中实现自定义逻辑。
如今,PIM 常被称为近内存计算,以避免与内存内计算混淆。近内存架构与传统冯·诺依曼架构的关键区别如下:
1. 计算逻辑靠近内存放置,通常使用高带宽电路集成技术(如 2.5D 和 3D 集成),以利用内存内部可用的大内存访问带宽。
2. 提供对内存单元中数据进行基本读写访问的内存单元、内存阵列和外围电路通常保持不变。
2.5D 集成电路采用硅中介层或有机中介层连接内存芯片和逻辑芯片,与传统的印刷电路板(PCB)上的引线键合相比,实现了高布线密度和功率效率。3D 集成使用硅通孔(TSV)和微凸块等层间连接技术来堆叠 DRAM 层。这两种技术都有助于提供大的内部内存带宽,并且逻辑芯片可以使用针对逻辑优化的不同工艺技术,从而推动了堆叠内存中的 PIM 发展。此外,访问内存单元的基本架构和协议保持不变,节省了构建全新内存设备的巨大设计成本。由于这些原因,一些近内存计算设备已经在市场上出现。
需要注意的是,一般-purpose core 不适合用于 PIM 以提供灵活处理,原因如下:
- 这些系统中的可用内存带宽非常高,具有数十个核心的通用多核处理器难以充分利用 3D PIM 的优势。
- 许多用命令式编程语言编写的应用程序利用时间和空间局部性,从缓存层次结构中获得显著好处,而 PIM 很少有这样的缓存结构。PIM 的宽内存带宽更适合能够暴露并行性或需要大带宽的应用程序。
- 与 CPU 芯片相比,PIM 中可分配给逻辑的面积较小。由于工艺技术的差异,PIM 中逻辑的成本通常比一般逻辑芯片更差。
- 一般核心的散热要求往往具有挑战性。
2.1.2 内存内计算
内存内计算是一种新的以内存为中心的计算范式,继承了 PIM 和近内存计算的精神。与近内存计算将逻辑电路独立于内存结构实现不同,内存内计算将内存单元、内存阵列和外围电路紧密参与到计算中,通常需要对它们进行结构修改或添加特殊电路来支持计算。
历史上,内存内计算被认为是一种经济上不可行的设计。修改内存单元会给内存设计带来不小的再投资成本,因为当前内存架构的技术已经针对统一的单元结构进行了深度优化。此外,修改后的单元设计可能会大幅降低密度,使得以内存为中心的架构难以在性能与面积(或性能与成本)之间取得平衡。
随着非易失性存储器(NVM)的出现,内存内计算的想法被重新审视。某些 NVM 具有在模拟域中进行计算的理想物理特性,能够在对内存阵列进行最小设计更改的情况下实现内存内计算。此外,内存单元的非易失性解决了 DRAM 单元破坏性读取访问的问题,避免了在计算前进行复制的操作。然而,模拟域中的内存内计算仍然是一种具有挑战性的技术。例如,由于工艺变化和扩展的电流路径存在的非理想性可能会影响计算结果。而且,随着处理的位数增加,数模转换(DAC)和模数转换(ADC)的成本会变得过高。
研究人员还重新审视了为现有内存基板(SRAM、DRAM 和 NAND 闪存)设计的内存内计算。他们解决了上述挑战,并利用了这些内存的成熟技术。一些研究工作提出在 NVM 中进行数字化计算以提高可靠性。
内存内计算方法可以进一步细分为两类:
-
内存内(阵列)或 IM - A
:使用特殊的计算操作(如 MAGIC 和 Imply)在内存阵列内产生计算结果。IM - A 架构可以提供最大的带宽和能源效率,因为操作发生在内存阵列内部,对于简单操作也能提供最大的吞吐量。然而,复杂功能可能会导致高延迟。此外,IM - A 通常需要重新设计内存单元以实现特殊的计算操作,扩展正常的位线和字线结构。由于单元和阵列的设计和布局是针对特定电压和电流进行高度优化的,任何单元和阵列访问方法的改变都需要大量的重新设计和特性化工作。此外,有时还需要修改外围电路(如字线驱动器和感测放大器)来支持 IM - A 计算。因此,IM - A 包括(a)内存阵列有重大变化的 IM - A,以及(b)内存阵列有重大变化且外围电路有轻微变化的 IM - A。
-
内存内(外围)或 IM - P
:在周边电路内产生计算结果。IM - P 可以进一步分为仅处理数字信号的数字 IM - P 方法,以及在模拟域中进行计算的模拟 IM - P 或 IM - P(模拟)方法。修改后的外围电路允许进行超出正常读写的操作,如与不同单元交互或对读取电压进行加权。这些修改包括支持字线驱动器中的多行激活以及用于多级激活和感测的 DAC/ADC。它们设计用于从逻辑运算到向量矩阵乘法中的点积等算术运算。虽然结果在周边电路中产生,但内存阵列也进行了大量的计算。外围电路的变化可能需要与传统内存不同的阵列电流/电压,因此 IM - P 可能会使用略有不同的单元设计以提高鲁棒性。为支持复杂功能而添加到外围的额外电路可能会导致高成本。
内存内计算与近内存方法相比,能够实现对数据的广泛大带宽访问,不仅可用于解决内存墙问题,还可用于大规模并行处理。
2.1.3 近内存计算与内存内计算的比较
以下是传统冯·诺依曼架构(基线)、近内存计算(NM)、IM - A 和 IM - P(数字和模拟)架构的比较:
|架构|单元修改|外围修改|密度(单元/总体)|内存与计算单元带宽|能量|逻辑面积|计算延迟|可靠性与 ECC 支持|
| ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | ---- |
|基线|否|否|高/高|低|高|高|低|高|
|NM|否|否|高/低 - 中|中|中|中|低|高|
|IM - P|否|是|高 - 中/高|高|低|低 - 中|中 - 高|中|
|IM - P(模拟)|否|是|高/低|高|低|低 - 中|中|低|
|IM - A|是|是|低/低|高|低|低|高|中|
从表格中可以看出,不同架构在各个方面存在明显差异。例如,在单元和外围修改方面,基线和 NM 不需要修改,而 IM - A 需要对单元和外围都进行修改;在能量消耗方面,内存内计算(IM - A、IM - P)通常比基线和 NM 更低,因为数据移动减少。
2.2 离散加速器与集成内存层次结构
以内存为中心的架构将内存和计算的角色结合在一个内存模块中。一个 NM 或 IM 内存模块可以设计为离散加速器,也可以设计为集成到现有内存层次结构中的加速器。
2.2.1 离散加速器
离散加速器可以无限制地完全访问其内存空间,类似于暂存器内存。离散的内存空间使加速器与操作系统的分页策略、一致性协议、数据加扰和地址加扰解耦,还提供了灵活的数据安排控制。特别是,大多数 IM 架构需要将操作数对齐到特定阵列的特定列中,或者对输入进行转置以进行位串行处理,离散加速器可以轻松支持这些特定于架构的数据布局。用户界面可以作为与驱动程序链接的库函数调用提供,类似于 ASIC 加速器。
然而,离散加速器的一个重要缺点是,它们仍然需要通过外部链接(如 PCIe)从内存层次结构加载数据,这可能成为瓶颈。商品加速器(如 GPU)也存在同样的问题,GPU 通过 PCIe 总线在主机内存和自身之间复制数据需要花费不少时间。不过,这种数据加载成本可以通过随着时间的推移重复使用数据来分摊,因此能够实现高性能的应用程序通常限于具有高重用性或高 GOPs(千兆操作)的应用程序。
以下是近内存计算和内存内计算相关技术的流程图:
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;
A([开始]):::startend --> B(内存墙问题):::process
B --> C{解决思路}:::decision
C -->|计算靠近内存| D(近内存计算):::process
C -->|内存参与计算| E(内存内计算):::process
D --> F(处理内存PIM):::process
F --> G(3D堆叠技术推动):::process
E --> H(IM - A):::process
E --> I(IM - P):::process
H --> H1(内存阵列重大变化):::process
H --> H2(内存阵列重大+外围轻微变化):::process
I --> I1(数字IM - P):::process
I --> I2(模拟IM - P):::process
D --> J(离散加速器):::process
D --> K(集成内存层次结构):::process
E --> J
E --> K
J --> L(优点:灵活数据布局):::process
J --> M(缺点:数据加载瓶颈):::process
K --> N(与现有架构融合):::process
L --> O([结束]):::startend
M --> O
N --> O
综上所述,近内存计算和内存内计算为解决内存墙问题提供了新的思路和方法,不同的架构和实现方式各有优缺点,适用于不同的应用场景。在未来的计算系统设计中,需要根据具体需求综合考虑这些因素,选择最合适的技术方案。
3. 内存计算在不同设备中的应用
3.1 通用处理器中的内存计算
内存对于所有计算设备都至关重要,无论是通用处理器还是加速器。以最新的英特尔服务器级至强处理器为例,它仅最后一级缓存就占用了 35MB。在通用处理器中使用内存进行计算是一种可行且有利可图的方法。
通用处理器在处理各种任务时,内存的高效利用能够显著提升性能。将内存重新用于计算,可以减少数据在内存和计算单元之间的移动,从而降低能耗并提高处理速度。例如,通过利用内存内计算技术,处理器可以在内存阵列中直接进行一些简单的计算操作,避免了将数据频繁传输到计算核心的开销。
3.2 加速器中的内存计算
加速器在特定领域的计算中具有显著优势,如谷歌的张量处理单元(TPU)为片上存储分配了数十 MB 的空间。对于加速器而言,内存计算同样具有重要意义。
以 TPU 为例,其设计目标是高效处理深度学习任务。在这些任务中,大量的数据需要进行矩阵乘法、卷积等运算。通过采用内存内计算技术,TPU 可以将数据存储和计算操作紧密结合,减少数据传输延迟,提高计算效率。例如,在处理大规模神经网络时,内存内计算可以使数据在内存阵列中直接进行计算,避免了数据在不同组件之间的频繁移动,从而加速整个训练和推理过程。
4. 编程模型与编译器需求
计算能力强的内存需要一种能够将应用程序中的并行性和数据移动暴露给底层硬件,并充分发挥其潜力的编程模型和编译器。
4.1 编程模型的多样性
不同的内存计算架构可能需要不同的编程模型。例如,对于能够暴露并行性的应用程序,适合采用支持并行计算的编程模型,如 OpenMP、CUDA 等。这些编程模型允许开发者明确指定代码中的并行部分,从而充分利用内存计算架构的并行处理能力。
对于需要大带宽的应用程序,编程模型需要能够有效地管理数据传输,以确保数据能够及时到达计算单元。例如,一些编程模型提供了数据预取和缓存管理的功能,帮助优化数据访问模式,提高带宽利用率。
4.2 编译器的关键作用
编译器在将高级编程语言编写的代码转换为能够在内存计算架构上高效运行的机器代码方面起着关键作用。编译器需要能够识别代码中的并行性和数据移动模式,并将其映射到底层硬件资源上。
例如,编译器可以对代码进行优化,将一些计算操作分配到内存阵列中进行,以减少数据传输。同时,编译器还可以根据不同的内存计算架构特点,调整代码的执行顺序和数据布局,以提高性能和能源效率。
以下是编程模型和编译器在内存计算中的作用流程图:
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;
A([应用程序代码]):::startend --> B(编程模型):::process
B --> C{并行性与数据移动}:::decision
C -->|识别并行性| D(并行编程模型):::process
C -->|管理数据移动| E(带宽优化编程模型):::process
D --> F(编译器):::process
E --> F
F --> G(代码优化):::process
G --> H(映射到硬件资源):::process
H --> I(生成机器代码):::process
I --> J([可执行程序]):::startend
5. 总结
5.1 不同架构的特点总结
| 架构 | 特点 | 适用场景 |
|---|---|---|
| 近内存计算(NM) | 计算逻辑靠近内存,内存单元和外围电路基本不变,带宽和能耗适中 | 适合对现有架构改动较小,需要一定带宽提升的应用 |
| 内存内计算 - 阵列(IM - A) | 在内存阵列内计算,带宽和能源效率高,但可能需要对内存阵列和外围电路进行较大修改,延迟较高 | 适合对带宽和能源效率要求极高,对延迟不太敏感的大规模并行计算任务 |
| 内存内计算 - 外围(IM - P) | 在周边电路内计算,可分为数字和模拟方法,带宽高,能耗低,对内存单元修改少,但可能需要对外围电路进行修改 | 适用于多种内存技术,需要一定灵活性的计算任务 |
5.2 未来展望
随着数据密集型应用的不断增加,内存墙问题将变得更加突出。近内存计算和内存内计算作为解决这一问题的有效方法,具有广阔的发展前景。
未来,我们可以期待看到更多的研究工作致力于优化这些技术,提高其性能和可靠性。例如,进一步改进内存单元的设计,以降低修改成本并提高密度;开发更高效的编程模型和编译器,使开发者能够更轻松地利用内存计算的优势;探索新的应用场景,将内存计算技术应用到更多领域。
同时,不同架构之间的融合也可能成为未来的发展趋势。例如,将近内存计算和内存内计算相结合,充分发挥它们各自的优势,为不同的应用场景提供更灵活、高效的解决方案。
在选择内存计算技术时,开发者需要综合考虑应用的特点、性能需求、成本等因素,选择最合适的架构和实现方式。通过合理运用这些技术,我们可以构建更加高效、节能的计算系统,满足未来计算的需求。
超级会员免费看

被折叠的 条评论
为什么被折叠?



