简介
持久内存 (PMEM) 技术提供(每个双路系统最高 6 TB)速度接近动态随机访问内存的大量字节可寻址非易失性内存,且只需 DRAM 的一小部分成本,即可为内存计算领域带来革命性的变化。内存计算最显著的优势包括缩短应用启动时间(无需重新创建内存数据结构)和增加内存容量。鉴于这些优势,关于高性能计算 (HPC) 是否也可以利用 PMEM 技术的问题出现了。
本文将潜在影响分为系统、中间件和应用三个方面,并从这三个方面探讨这一问题。我们将针对每个方面提供一般信息、潜在架构源代码变更和实际应用示例。本文并未涵盖所有可能情况,由于这是一项新技术,因此本文举出的示例还未最终确定。
持久内存 (PMEM) 技术概述
PMEM 概述
PMEM 技术可被视为 NVM 技术的最新进展。NVM 技术包括传统的磁带、硬盘和软盘,只读内存芯片和光盘,以及如今市面上最新的固态盘 (SSD)。与 DRAM 相比,所有这些技术的共同点是容量大但性能低。这会创建两个级别的系统存储(主存储和二级存储),这两种存储我们很熟悉。
主存储专为快速运行而设计,以便在计算过程中为 CPU 提供所需的所有“热”数据。二级存储用于保存目前不需要但在断电后仍能留存的“冷”数据和程序。尽管二级存储可用于存储“热”数据,但却在 DRAM 容量不够时使用(例如将内存页面切换为磁盘)。由于不可忽略的性能影响,此方法不可取。简言之,主存储是快速、小型的易失性存储,而二级存储是缓慢、庞大的持久性存储。
考虑到这一点,我们可以明白,这两种存储在设计方面的一个关键差异在于数据访问粒度。主存储支持 CPU 寻址并随机访问单个字节的数据,二级存储中的数据访问单元通常为 4KB 大小(有时甚至更大)的数据块。二级存储需要通过这种批量数据访问方式来弥补访问延迟,这比主存储的访问延迟还要大几个数量级。由于存在这种主存储和二级存储之间的访问粒度差异,因此需要为应用创建两种数据模型:
- 主存储的数据模型更加复杂和丰富,如树、堆、链表、哈希表等
- 二级存储的数据模型不太灵活,如标记语言(例如 XML)中的序列化数据结构、逗号分隔值文件、结构化查询语言表等
PMEM 有何不同?
PMEM 的创新性在于它支持字节寻址且速度快(如主存储),同时仍具备二级存储的许多优势,如大容量、持久性和每字节低成本(见图 1)。由英特尔和美光科技* 联合开发的 3D Xpoint™ 内存技术除了提供接近 DRAM 的访问延迟之外,还具有所有这些优势。CPU 可直接访问 PMEM DIMM,从而消除 PCIe *总线传输协议等中间开销。尽管我们仍需要使用二级存储来实现低成本的海量数据归档,PMEM 的定位是成为一种允许大量应用和系统统一其数据模型的技术。
图 1.PMEM 技术与 DRAM 和固态盘的性能和容量对比。该图还显示了 PMEM 如何实现字节寻址和持久性。
希望在 PMEM 设备上保留某些数据结构的应用需要确保对数据结构的修改是在原子级别完成的(例如通过使用事物),以避免未在断电前按时刷新的 CPU 缓存中存储的数据造成损坏。不过,如果应用只需要增加主存储容量,就可以放弃这一部分。这可以在内存受限的 HPC 中派上用场,我们将在下文中看到。
系统视角
PMEM 为 HPC 带来的第一个优势是更大的主存储容量(每个双路系统 6 TB)。若要了解 HPC 应用可能如何利用 PMEM,我们首先要从概念上了解这种新技术如何适应整个内存层级。
****三种逻辑架构
如图 2 所示,应用在集成 PMEM 时可以使用三种逻辑架构:DRAM 作为缓存、PMEM 作为 DRAM 扩展以及 DRAM 作为临时缓存。
图 2.使用 PMEM 作为内存受限应用的扩展容量的三种逻辑架构
在 DRAM 作为缓存的场景(见图 2a)中,应用将使用 PMEM 作为内存层级内的新层。应用为其 PMEM 中的数据结构分配内存,因此使用 PMEM 作为主存储,而仅将 DRAM 用作四级缓存。但如果采用这种方法,CPU 在常规计算过程中使用(即寻址)的所有数据仍然是针对 DRAM 的。这意味着,DRAM 和 PMEM 之间的数据移动需要使用某种显式缓存支持代码进行处理。
在 PMEM 作为 DRAM 扩展的场景(见图 2b),应用将使用所有可用内存容量作为单个内存池。可以先在 DRAM 中分配内存;如果需要更多内存,则在 PMEM 中继续分配。通过采用这种方法,CPU 在常规计算过程中使用的数据将来自 DRAM 或 PMEM,从而导致访问延迟变化,具体情形取决于 CPU 访问哪些数据。
在 DRAM 作为临时缓冲区的场景(见图 2c)中,应用由不同的计算内核组成,每个内核使用不同的内存使用模式。根据每个内核的具体情况,可以使用一种内存或另一种内存。此类内核的一个示例是 3D 快速傅里叶变换 (3D-FFT),后者会对数据进行转换以用于谱相方法。3D-FFT 需要对相同的数据点进行多次传递,因此最好始终针对 DRAM 进行计算。请注意,逻辑架构 (a) 实际上是 (c) 的一个子集。
模板应用
内存受限的大规模 HPC 应用将直接受益于分配更大规模问题的能力。此类应用的一个示例是模板(即最近邻居)计算。模板应用用于通过迭代有限差分技术实施偏微分方程求解器。求解 3D 热方程式是一个典型的模板问题。
Ht+1 [i,j,k]=a Ht [i,j,k]+b (Ht [i-1,j,k]+Ht [i,j-1,k]+Ht[i,j,k-1]+Ht[i+1,j,k]+Ht [i,j+1,k]+Ht [i,j,k+1])
该方程式是一个模板,代表针对 3D 网格中的每个数据点 (i,j,k) 执行的单个不适当(即新值存储在 Ht+1 中而非 Ht 中)Jacobi 迭代。由于这种访问模式是固定且可预测的,数据可在使用前智能预取到 DRAM 中,因此是 DRAM 作为缓存架构的理想之选。事实上,这种数据预取 在文献中被称为“阻塞”。 例如,通过阻塞,数据被拆分为大小相同的核心块,这些数据块很好地融入到三级缓存中,可以大大减少缓存未命中。同样,核心块可以随后被拆分为用于并行化的线程块甚至 寄存器组,以充分利用数据级并行性(即矢量化)。
按照这一逻辑,我们可以考虑一下DRAM 块,它是一个额外的阻塞层,用于优化到 DRAM 的数据预取。图 3 显示了用最左边的新增层进行阻塞的概述。
图 3使用为 PMEM 添加的额外层进行阻塞,预取模板应用的数据。此图是图 2 的修订版本
中间件视角
HPC 应用利用 PMEM 的另一种方式是增强位于中间件层的库和服务,使其具有 PMEM 感知能力。这种方法的目的是将这种新技术的优势带入到应用中,同时避免繁重的编码工作。
能够感知 PMEM 的检查点/重新启动
通过在本地节点级别添加一个 PMEM 感知缓冲区,可增强高性能计算中的检查点/重新启动 (C/R)。这些检查点可以从 PMEM 异步传输到远程分布式文件系统 (DFS) 或中间 突发缓冲服务器,且不会对执行进度有很大影响。这种 C/R 使用方式在社区中被称为“分级 C/R”(见图 4)。
持久性可确保在所有进程完成 PMEM 的检查点后(甚至在完成到 DFS 的远程复制之前),最后一个检查点完成的应用随时可用。当然,只要有问题的故障不影响保存在 PMEM DIMM 上的数据,情况就会如此。持久性还可以帮助降低 DFS 远程检查点的频率。经典的杨氏公式 (Tc= √(2 × C ×MTBF)) 表明,检查点的频率 (1/Tc) 与平均故障间隔时间 (MTBF) 成反比。由于 PMEM 为数据增加了额外的安全层,故障的可能性降低,从而使 MTBF 增加。频率较低的远程检查点意味着整体开销较小(远程传输大量数据并不便宜)。
尽管有执行本地检查点的其他替代方案(如固态盘),PMEM 的独特功能很可能使其成为这方面的关键技术。
图 4.PMEM作为第一级的分级检查点。
由于 PMEM 的容量大于 DRAM,因此可以一次存储多个检查点(如需要)。通过协调远程复制与低应用网络流量的状态,这一缓冲可以帮助提高网络利用率。
MPI-PMEM 扩展
在高性能计算领域,最知名的中间件可能就是 消息传递接口 (MPI)了。本节将介绍为 MPICH* 编写的两个扩展:美国阿贡国家实验室开展的 MPI 开源实施。您可以在链接的 GitHub* 库中下载、使用并修改。当然,这些扩展并不是唯一可能的扩展。
第一个扩展位于 mpi_one_sided_extension目录下,通过允许进程声明“持久窗口”,使得 MPI 具有单向通信 PMEM 感知能力。这些窗口的生命周期超过了应用的执行时间,对 C/R 很有用。另一个用例是参数扫描场景,需要使用相同的输入数据运行相同的应用,但使用的输入参数不同。对于这些用例,输入数据只能从二级存储加载到 PMEM 中,然后重复用于多次执行,因此可缩短应用启动时间。
第二个扩展位于 mpiio_extension2目录下,使用两种模式将 PMEM 集成到 MPI-IO 中:(1) PMEM_IO_AWARE_FS 和 (2) PMEM_IO_DISTRIBUTED_CACHE。在 (1) 中,连接到所有节点的所有可用 PMEM DIMM 都合并为一个逻辑视图,以形成 PMEM DFS。当前节点中不存在的数据请求将使用代理转发到适当的节点。在 (2) 中,连接到节点的 PMEM DIMM 作为存储在远程 DFS 中的数据的巨大缓存(每个双路系统高达 6 TB)。如果我们还认为 PMEM 将享有接近 DRAM 的速度,那么不能忽视模式 (2) 提升 MPI-IO 性能的潜力。
持久工作流引擎
科学界使用的另一类 HPC 中间件是工作流引擎 (WE),例如Galaxy* 或 Swift*。为工作流程运行的作业必须将工作分成单独的任务。这些任务彼此独立运行(它们与数据无关,因此它们不共享任何状态,并且所有输入数据都按值传递),并且每个任务通常都是一个独立的软件。您可以将 WE 视为粘合不同软件的粘合剂,它们本身不会相互通信,从而创建一个整体 ─ 将输出与输入、调度和分配所需资源连接起来。
WE 的一个主要问题在于,在大多数情况下,任务通过文件(有时通过数据库引擎)相互通信。任务通常用于执行特定分析,它读取其输入文件并将结果写入输出文件,这些输出文件将被其他任务用作输入等等。在这里我们可以看到如何利用 PMEM 为工作流的中间数据创建快速缓存,而非在很大程度上依赖文件。您还可以通过优化任务直接使用特定的内存数据结构,而不必像平时一样利用平面文件进行重新创建,这也可以帮助简化代码并加快执行速度。
应用视角
在应用级别,应用本身直接负责定义哪些数据结构应该是永久的,并采取相应行动(例如通过原子方式写入,以避免可能的损坏)。英特尔正在通过存储和网络行业协会 (SNIA) 与业内的其他主要厂商密切合作,该协会开发了基于 NVM 编号模型 (NPM) 标准 的 持久内存开发工具包 (PMDK)。PMDK 由多个开源库和 API 组成,其目标是帮助程序员调整其应用,使其适应 PMEM。尽管不是强制使用,但我们推荐您使用,特别是新手。
对于 HPC 应用,特别是模拟,持久数据结构的优势尚不明确。当我们考虑访问延迟时,我们需要问:持久性具有哪些额外优势,以弥补其访问延迟较长和交易开销大的缺点?此外,HPC 模拟的数据会随着时间推移而发生变化,是否值得留存很快会改变的数据?除了检查点之外,很难想出持久性能够为 HPC 模拟带来的其他明显优势。如果您不这样认为并能提供好的用例,请联系我。
不过,与 HPC 模拟结合使用的其他应用可以从持久数据结构中获益。现场可视化就是一个示例。
借助 PMEM 进行交互式现场可视化
现场可视化 是一种旨在避免运行模拟的 HPC 系统与渲染图形的可视化系统之间过多移动数据的技术(见图 5)。可视化本身(或其一部分,因为可视化通常表示为一系列数据转换)是在模拟生成数据的同时在 HPC 系统中完成的,而不是将数据检查点设置到稍后作为可视化输入的文件系统中。可视化库在每个时步的末尾被调用,原始数据在大多数情况下通过引用(尽可能避免数据复制)进行传递。只有在完成可视化后,模拟才能继续进行下一步。
图 5。(a) 传统 HPC 可视化与 (b) 现场可视化在 (a) 中,模拟执行昂贵的检查点(第 2 步),以存储用于可视化的原始数据。但在 (b) 中,大部分数据转换和渲染(如果不是全部)是在 HPC 系统中执行的。然后,转换和/或渲染的数据(比原始数据小)将被转发到可视化应用中,或存储起来以供未来使用。
这种方法的局限之一是缺乏灵活性。一旦模拟进行到下一个时步,来自上一个时步的数据通常会在内存中重写,这会限制与可视化交互的机会,例如更改用于着色的参数值,添加或移除过滤器,切片,添加额外灯光, 移动摄像头等等。此外,通过重启可能已经运行数天的模拟来改变一些可视化参数也是不可行的。
在这里,PMEM 可以允许时步窗口的持久性,从而提供帮助。这个窗口可以通过更改参数以及从窗口开始重新渲染模拟来进行模拟交互。您可以设想一下这种情形:用户对目前生成的可视化效果不满,可能想在继续模拟之前研究一下如何使用不同的可视化选项和参数,但不想重启。由于窗口是持久性的,因此比模拟的生命周期长。从理论上而言,模拟完成后很长时间都可以访问可视化并与其交互。
我正在使用 PMDK 的libpmemobj 库开发一个借助 PMEM 进行交互式现场可视化的原型。我选择将 HPC 社区中众所周知的 ParaView* 作为可视化应用。我将向所有人公布我的进展以及从这一精彩项目中学到的经验教训。
总结
文本介绍了如何借助 PMEM 技术提高高性能计算能力。我们从 PMEM 的一般定义开始,然后介绍了它对系统、中间件和应用的潜在影响,以及潜在的架构代码变更和每个方面的实际应用示例。本文所举的所有示例仍在制定中,可能会发生改变。欢迎社区提供新的想法和意见,我的电子邮箱为 eduardo.berrocal@intel.com。
关于作者
Eduardo Berrocal 于 2017 年 7 月加入英特尔,担任云软件工程师。他拥有伊利诺斯州芝加哥伊利诺理工学院 (IIT) 的计算机科学博士学位。Eduardo Berrocal 的博士研究课题是 HPC 的数据分析和容错。之前,他曾做过贝尔实验室(诺基亚)的暑期实习生、阿贡国家实验室的研究助理、芝加哥大学的科学程序员和 Web 开发人员以及西班牙 CESVIMA 实验室的实习生。
资源
一流多核架构上的模板计算优化和自动调整, Kaushik Datta 等人http://mc.stanford.edu/cgi-bin/images/e/ec/SC08_stencil_autotuning.pdf。
GitHub 中 MPI-PMEM 扩展代码的链接。
持久内存开发工具包 (PMDK)。
非易失性内存编程 (NMP) 标准:https://www.snia.org/tech_activities/standards/curr_standards/npm。
开源多平台数据分析和可视化应用 ParaView:https://www.paraview.org/。
现场可视化:一些一流用例, Marzia Rivi 等人,CINECA,贝尔格莱德大学贝尔格莱德物理研究所科学计算实验室http://www.prace-ri.eu/IMG/pdf/In-situ_Visualization_State-of-the-art_and_Some_Use_Cases-2.pdf。
消息传递接口 (MPI)。
基于用户级 InfiniBand 的文件系统和用于突发缓冲区的检查点策略,Kento Sato 等人,2014 年第 14 届 IEEE/ACM 国际集群、云和网格计算 (CCGrid) 研讨会,http://ieeexplore.ieee.org/abstract/document/6846437/。
MPICH: 高性能、可广泛移植的消息传递接口 (MPI) 标准实施http://www.mpich.org。
Galaxy 工作流引擎项目:https://galaxyproject.org/。
Swift 工作流工具:http://swift-lang.org/main/。
优化不确定执行尺度的多级检查点模型, Sheng Di 等人,高性能计算、网络、存储和分析国际会议论文集 (SC’14),2014 年,https://dl.acm.org/citation.cfm?id=2683692。
文章评论