查看原文
其他

HPC应用程序中的I/O访问模式:360度调查

常华Andy Andy730 2024-03-16

Source: JEAN LUCA BEZ, I/O Access Patterns in HPC Applications: A 360-Degree Survey, July 29, 2023

高性能计算(HPC)的I/O(输入/输出)堆栈因多个软件层、这些层之间的相互依赖以及每个层次的不同性能调优选项而变得复杂。在这个复杂的堆栈中,对于“I/O访问模式”的定义已被重新界定,用于描述应用程序在不同层次的堆栈中进行数据写入或读取的情况,而这往往包含了不同的特征集。由于无法做出任何假设,因此在每项新研究中重新定义这个模式的含义已经成为常见现象。本调查旨在提出一个基本分类方法,汇集过去20年来I/O业界的知识。这个定义可以作为HPC I/O研究人员和开发人员的共同基础,用于应用已知的I/O调优策略并设计改进I/O性能的新策略。我们希望总结并达成共识,采用业界多年来已经使用的常见特性来描述一个模式。

1 引言

在高性能计算(HPC)中,“I/O访问模式”或“I/O特征”广泛用于表达应用程序进行输入和输出(I/O)操作的方式[21]。尽管这个术语被广泛使用,但尚没有全球公认的约定来描述哪些特征定义了I/O访问模式,并且这些特征在描述HPC I/O软件堆栈中的不同层级时有何不同。例如,有些研究不将时间特征视为访问模式描述的一部分[22],而其它研究则将其纳入考虑范围[27,219]。此外,一些研究描述的是高层次库所看到的访问模式[26,41,66],而其它研究则描述I/O中间件所看到的模式[7,216],还有些描述的是底层文件系统接收到的模式[24,128,237]。因此,每次进行“I/O访问模式”的讨论时,不得不重新确定其准确含义,因为不能做出任何假设。

本文旨在提出一个基本分类方法,汇集过去20年来I/O业界的知识,以供研究人员和应用程序开发者用于定义应用程序的I/O访问模式。这个定义可以作为一个共同基础,用于应用已知的I/O调优策略,并设计新的策略来提高I/O性能。我们在这里提出的定义旨在总结并达成共识,采用业界多年来已经使用的常见特性来描述一个模式。它不是既定不变的,而是一个基本共识,可以扩展来适应不同领域的新应用。

除了巩固基于共同特征的分类法之外,我们的调查对当前和未来该领域的研究具有实际应用。例如,大量旨在改善应用程序I/O性能的现有优化技术都依赖于对访问模式的定义。尽管它们应用的策略不同,但它们都通过修改应用程序访问其数据的方式(即其I/O访问模式)来更适合I/O堆栈的底层层次。请求聚合、重新排序、调度和集体操作[44,59,60,114,197,216]是优化机制在I/O堆栈的不同层级上应用的一些例子。一般来说,这些优化通常可以改善特定系统部署和I/O模式的性能,但并非所有情况下都能取得改进。此外,它们通常需要准确地将这些技术应用于由一组访问模式表示的工作负载。

随着来自不同领域的新型应用程序正在利用HPC平台,系统变得更加复杂以处理更多并发应用程序,对于那些寻求在运行时准确检测I/O访问模式并自动调整其参数的系统来说,准确地检测I/O访问模式变得至关重要。这种检测使得它们可以对观察到的模式进行决策并应用特定于这些模式的一组优化技术。拥有一个已建立的分类体系和明确定义的特性可以帮助弥合描述访问模式与将其映射到现有技术之间的差距,从而使基于人工智能和自动调优机制可以在复杂的参数空间中导航,找到可以应用于观察到的I/O访问模式的优化和配置。

贡献

虽然术语“I/O访问模式”在已发表的文献中被广泛使用,但尚没有一项研究包含、讨论和对其进行分类,以适应HPC中使用该术语的广泛程度。White等人[219]提出了用于HPC作业时间I/O模式的分类体系,以帮助自动检测性能不佳的作业。Boito等人[21]涉及了HPC I/O堆栈的若干关键点,包括访问模式提取。然而,这两者都存在重新定义访问模式含义的问题。此外,这些定义并未涵盖I/O的所有特征以及在浏览并行I/O堆栈的不同层级时它们的影响。在这项工作中,我们旨在为I/O访问模式提供一个更广泛的分类体系,考虑到时间行为,并将其它业界常用的特性整合进来,并描述这些模式在遍历HPC I/O堆栈时如何表示、使用和转换。

本文的其余部分安排如下。第2节讨论传统的HPC I/O软件堆栈。访问模式的讨论分为四个部分,分别代表堆栈中的层级。在第3节,我们描述科学应用程序使用的常见数据模型。第4节讨论这些数据模型如何被高层次I/O库表示。第5节讨论了中间件库使用的I/O访问的转换。最后,在第6节中,我们呈现了文件系统的视角。在第8节,我们介绍了常见的I/O基准和核心,用于在HPC I/O堆栈的不同层级中展示访问模式,并在第9节中,我们描述了通过使用分析和日志跟踪来可视化这些模式的常用工具。在第10节中,我们总结了这项调查的贡献,现有的差距,并强调了进一步研究和发展的机会。

2 HPC I/O堆栈


为了支持串行或并行科学应用程序的输入和输出(I/O)工作负载,HPC系统提供了一个多层次的软件堆栈,如图1所示。在应用程序和存储硬件之间,并行I/O堆栈由高级I/O库、中间件I/O库、优化层和并行文件系统(PFS)组成。

图1:传统HPC I/O软件栈,包括应用程序和存储硬件之间的几个层次的库。

在遍历堆栈时,访问模式通常会通过一系列数据转换进行重塑,这些转换源自不同的抽象和数据模型之间的映射,并应用优化技术(如调度、聚合和压缩)后到达文件系统。此过程中有些上下文信息会丢失。例如,当请求到达文件系统层时,文件系统并不知道该请求的来源是哪个应用程序或进程,甚至不知道该请求是否经过任何数据转换以及经过了哪些转换。因此,应用程序可能认为它是以某种方式访问其数据,但实际上在堆栈的最底层可能完全不同。

高级I/O库被应用程序用于提供数据模型和文件管理抽象,以便实现数据可移植性和高性能。被广泛采用的库示例包括HDF5 [202]、NetCDF [119]/PnetCDF [121]和ADIOS [134]。这些库将应用程序的数据抽象映射到文件或对象,并以可移植文件格式对数据进行编码。这些库允许用户添加元数据来描述数据及其数据结构。除了这些并行I/O高级库外,还存在应用程序领域特定的库。其中,ROOT [5]和FITS [80, 217]分别服务于高能物理学和天文学业界。应用程序还可以直接使用消息传递接口I/O (MPI-IO) [46]、可移植操作系统接口I/O (POSIX-IO) [67]或标准输入和输出 (STDIO) 接口,以执行对文件系统的I/O。我们在第7.1.4节中讨论这些接口、它们的挑战以及它们对HPC I/O性能的已知影响。

在MPI I/O中,文件被视为有序的类型化数据项的集合。它提供比POSIX更高级别的数据抽象,允许用户定义对应用程序自然的数据模型。尽管如此,它支持使用独立和集体I/O调用定义并行写入和读取操作的复杂数据模式。此外,它允许在使用集体调用时利用优化机会。然而,对于HPC而言,POSIX I/O将文件视为字节序列。这个接口允许在文件和内存之间传输连续的字节区域,也允许通过从内存到文件的非连续字节区域来完全控制I/O操作。然而,在HPC场景中,这个接口很少天然地支持并行I/O。例如,POSIX不容易支持对文件的集体访问,而是留给程序员来协调访问并确保一致性。相比之下,STDIO将所有文件操作抽象成对字节流(输入或输出)的操作。它包含了C stdio.h函数族 [97],如fopen(),fprintf()和fscanf()。这些I/O函数在基因组学和生物学中常用于以文本格式存储测序信息 [182]。然而,STDIO函数并不直接支持对数据文件的随机访问。相反,它依赖于程序员创建流、在文件中寻找位置,然后按顺序从流中读取/写入字节。

I/O转发 [3] 最初用于Blue Gene,后来得到了扩展,旨在通过在计算节点和数据服务器之间创建一个额外的透明层来减少(计算)节点同时访问PFS服务器的数量。I/O转发技术不是应用程序直接访问PFS,而是定义一组I/O节点,负责接收来自应用程序的I/O请求并以受控的方式转发到PFS,允许优化技术(如请求调度、聚合和压缩)[2, 16, 159, 190, 232]重塑I/O请求的模式和流,以更好地适应底层层级。

在大规模系统中,应用程序依赖并行文件系统 (PFS) 提供全局持久性共享存储基础设施和跨多个分布式存储服务器的全局命名空间,以读写数据到文件中。并行文件系统包括两种具有不同角色的服务器:数据服务器和元数据服务器。后者处理有关文件的信息(例如大小和权限)以及它们在系统中的位置。Lustre [74, 93]、IBM Spectrum Scale (之前被称为GPFS) [174]、BeeGFS [87]、PVFS [36] 等是大规模HPC系统上常用的并行文件系统。为了实现高性能,这些文件系统通过使用数据条带化 [188] 来利用并行性,即将文件进行划分,并将数据分布到多个存储节点上的固定大小的块中。最后,PFS服务器在各种存储设备(如硬盘驱动器、固态驱动器或独立驱动阵列)上提供逻辑文件系统抽象。

总结(1)
多层次的软件和硬件HPC  I/O堆栈是复杂的。为了在HPC系统中访问数据,应用程序发出请求,而在遍历I/O堆栈时,这些请求会通过一系列数据转换进行重塑。这些转换源自各个层次中使用的数据模型之间的不同抽象和映射,结合了在到达文件系统和最终存储硬件之前应用的优化技术。

在接下来的章节中,我们将讨论观察到的HPC堆栈层中的I/O访问模式,从应用程序数据模型开始,逐渐穿过底层层次,直至文件系统处理这些请求。

3 应用数据模型与I/O访问模式


科学应用程序通常使用高级库(如HDF5、NetCDF、ADIOS)提供的数据抽象来更自然地表达问题和领域的数据结构。HPC模拟通常使用多维数据或网格、任意子集、点和曲线以及关键值来描述其数据对象[151, 181]。特别是网格数据对象可以进一步由结构化的直交、非均匀的直交、无网格点、结构化(曲线)、任意多面体、构造性实体几何(CSG)、无结构集合(UCD)和自适应网格细化(AMR)网格来表示。在图2中,我们展示了HPC应用程序中最常用的这些高级数据模型。

图2:HPC应用程序中常用的高级数据模型在不同科学领域的可视化表示。

例如,物理模拟依赖于有限元方法,通过将模拟域划分为较小的元素来离散化它。然后在这些元素上应用数值方法来求解微分方程。这些方法通常假设域被划分为一个结构化或非结构化网格,由较小、较简单的元素组成。前者相对于后者具有一些优势。它使用更简单,内存需求较小,因为其坐标可以计算而不必存储。然而在非结构化网格的情况下,计算是不规则的,导致间接、非步进(即连续数据访问之间没有间隔)或非连续的内存访问问题[153]。另一方面,结构化网格在表示某些域所需的复杂形状方面缺乏灵活性[14]。

均匀直交网格(图2(a))将计算域划分为一组矩形单元,拓扑和几何上都是规则的。如果将点和单元组织成1D平面,则通常用于表示图像数据。体积可以通过将该网格排列成多个叠加平面来表示。直交网格(图2(b))在其规则性上有所不同,其中点之间的间距可能会变化(在任何轴上),但行和列仍然与笛卡尔坐标系的轴平行。曲线网格(图2(c))或结构化网格(也称为映射网格或体贴体网格)与直交网格具有相同的拓扑结构,但允许网格的形状有更多的变化,因为它们可以弯曲成任何配置,而无需重叠或相交。这些网格不使用笛卡尔网格线,而是使用曲线坐标系,其中一个点坐标数组明确表示几何形状。曲线网格提供更紧凑的内存占用,并且在拓扑上是规则的,但几何形状是不规则的。它们用于有限差分计算,如低通滤波[64]、热传导和燃烧模拟[31]等。无结构网格(图2(e))是与几乎任何所需几何形状相符的镶嵌网格。然而,它们需要存储和恢复比结构化网格更多的信息,例如表达邻接连接列表。这些网格用于地震波[65, 91, 225]、流体动力学[79, 184]和热传导[130, 153]模拟。

图3:Array of Structures (AoS)或Structure of Arrays (SoA)在文件中的数据布局。

表1:内存中数据结构和文件中数据布局的映射。为了说明目的,我们限制在1D数组中。

高级数据模型可以使用两种数据布局来存储在文件中,关于交错方式:结构数组(AoS)或数组结构(SoA),如图3所示。内存中的连续模式意味着多个数组具有相同的基本数据类型,如整数、浮点数、双精度等。内存中的非连续模式,也称为“结构数组”或“派生数据类型”,表示由基本数据类型派生的复合数据类型。前者有助于在连续的内存位置上访问相邻的工作项,而后者通常从开发人员的角度来看更直观,因为每个结构都被保存在一起。一旦数据需要持久化存储在文件中,它可以使用相同的策略或与内存中表示数据的相反策略。表1通过比较使用HDF5时的内存和文件表示来描述这一点,例如以连续或复合方式存储数据。然而,这种表示也被其它I/O库和接口使用,如MPI-IO,其中可以定义数据类型来描述内存和文件布局。

由于应用程序的I/O请求需要穿过I/O堆栈,最终达到存储系统,它的I/O模式会被各种现有优化技术(如集体缓冲和数据筛选[7, 44, 136, 199, 216]、请求调度[6, 16, 20, 22]和请求聚合[96, 197, 208])重新塑造和转换。通常,这些转换对最终用户是透明的。因此,应用程序认为它正在进行的操作可能与I/O堆栈的其它层次感知到的应用程序行为不同。因此,有关应用程序如何访问其数据的信息可能会在整个堆栈中丢失。例如,当请求到达并行文件系统时,几乎不可能确定哪个rank发出了该请求,以及它最初是否是连续的。为了阐明这样的例子,如果I/O中间件库(如MPI-IO)应用了集体I/O优化,则只有聚合器会向PFS发出请求,只有他们会知道应该向哪些rank交换有关请求的数据。更进一步复杂的是,假设存在一个转发层[2, 98](或任何其它透明的中间件),可能合并或调度和聚合来自多个计算节点的请求,那么PFS将无法知道哪个应用程序rank最初发出了I/O请求。另一方面,当这些请求被转发到PFS(使用转发层),后者通常不知道它们来自哪些计算节点。只有I/O节点才有这些信息,可以将数据转发回来。

总结(2)
并行应用程序依赖于与问题域自然映射的数据模型。为了存储在文件中,数据必须由HPC I/O堆栈的中间层进行转换。因此,我们可以用于描述文件系统层面上的I/O访问模式的特征与在I/O堆栈中较高层次的视图上的特征不同。


4 高级I/O库中的访问模式

高级I/O库允许HPC应用程序更自然地表示科学模拟数据,而不受系统特定细节的限制。HDF5、NetCDF/PnetCDF、ADIOS、ROOT和FITS都是此类库的示例,它们分别提供一组API来表示复杂的多维数据、连续和非连续数据,旨在实现性能和可移植性,并提高生产率。

图4:HDF5中用于部分I/O的内存和文件表示之间常见的hyperslab选择的可视化表示。

HDF5(层次数据格式5)是一种著名的自描述文件格式和I/O库[202],提供灵活性、可扩展性和可移植性。它在许多科学领域广泛使用以管理各种数据模型[28]。HDF5使用数据空间对象的概念来控制数据在读取或写入时的数据传输。数据空间定义了文件和内存中数据的布局(即行、列等的组织方式)。当使用不同的布局表示给定数据集在内存或文件中时,库会重新排列数据。然而,源和目标都以定义数据空间的顺序存储为连续块。HDF5允许应用程序通过使用hyperslab和点来读取或写入数据集的一部分(部分I/O)。hyperslab是数据集的部分,其选择可以是数据空间中逻辑上连续的一组点,或数据空间中一组点或块的规则模式。图4描绘了HDF5中四种类型的部分I/O。

图5:使用HDF5库进行部分I/O操作的hyperslab选择示例。

HDF5 hyperslab可以看作是由四个数组定义的矩形模式:hyperslab起始位置的偏移量;分隔每个元素或块的元素数;沿每个维度选择的元素或块数;以及从数据空间选择的块的大小。图5描述了数据集中的一个hyperslab选择(左图)。

NetCDF为科学程序员提供了一种自描述的、与机器无关的可移植格式,用于存储面向数组的数据[119]。NetCDF-4是经典NetCDF文件格式的当前版本。NetCDF-4支持对经典NetCDF和HDF5文件的并行文件访问。对netCDF-4格式的并行I/O是通过HDF5库来支持的,对经典netCDF格式的并行I/O是通过PnetCDF来支持的。PnetCDF是用于访问NetCDF文件的高性能并行I/O库,提供更高级的数据结构(如多维数组的类型数据)。NetCDF-4读取和写入API函数允许定义hyperslab参数,例如起始索引和计数向量。例如,函数nc_put_vara_int()用于向一个变量写入整数值的数组,它有参数来指定数组的每个维度的起始索引以及相应的计数,指定要写入的数据值的块的边长。

可调整输入输出系统(ADIOS)[134, 139]为可移植性和可扩展的I/O提供了一个I/O抽象框架,以帮助科学应用程序在数据传输量超过传统文件I/O能力时。ADIOS与HDF5不同,它不是一个分层模型,而是处于比它更低的抽象层次上。然而,它也依赖于自描述的二进制打包(.bp)格式以实现快速元数据提取,但它可以使用不同的后端文件存储格式,如HDF5和netCDF。ADIOS还可以从大数据集中提取相关信息,在不同媒体之间传输和转换自描述数据变量和属性组。该库使用外部XML格式的元数据文件来描述变量、类型和从内存到磁盘的路径。它还具有用于缓冲和调度的内置优化模块[76]。ADIOS-2 API允许指定启动和计数向量,以设置MPI秩的偏移量和维度,分别。

ROOT [5]是一个面向对象的C++框架,最初是在高能物理(HEP)业界中设计的,用于高效地存储和分析百亿字节的数据。ROOT已被用于存储超过1EB的HEP事件[140]。在ROOT中,内存中的对象在达到文件中的二进制表示之前经历序列化和压缩。这些是自描述文件,包含一个头和遵循分层目录格式的数据。ROOT还可以在文件中使用列式表示,允许I/O优化,如部分读取(即仅读取相关列的子集)、预取和预读以提高性能。例如,在分析许多统计独立的碰撞事件时,高能物理应用程序受益于这样的文件布局。

FITS(灵活图像传输系统)[80, 217]是天文学中的一种标准数据格式。最初设想为数字图像的标准交换格式,FITS文件用作存储ASCII或二进制表格数据的工作数据格式,除了图像和光谱。文件由一个或多个头和数据单元(HDU)的序列组成。头部由ASCII卡片图像组成(通常读入字符串数组变量),描述与关联数据单元的内容,这可能是频谱(向量)、图像(数组)或ASCII或二进制格式的表格数据(通常作为结构读取)。表格数据不能出现在第一个HDU中,而图像和向量数据可以出现在任何HDU中,随后的HDU(或主要HDU之后)也称为扩展。

总结(3)
高级I/O库提供了一层抽象,使应用程序可以轻松地将其数据模型映射到文件。其中几个库旨在提供文件格式的可移植性,并具备自我描述功能,允许向数据添加元数据。在这一层次上,多维数据结构的I/O访问模式旨在隐藏将数据模型转换为文件布局的复杂性。


5 I/O中间件层的访问模式

高级I/O库提供了一层抽象,使得应用程序可以将其数据模型轻松映射到文件。其中一些库的设计目标是提供文件格式的可移植性,以及自描述特性,允许向数据添加元数据。在这一层的多维数据结构的I/O访问模式旨在隐藏将数据模型转换为文件布局的复杂性。

在到达持久介质之前,应用程序的请求可以经历一系列由I/O优化所实现的数据转换。例如,使用MPI-IO,如果一组MPI秩知道每个秩正在访问文件的哪些部分,就可以将这些请求合并成更少、更大且更连续的访问,这些访问跨越文件的大部分区域。当在客户端级别应用时,这种优化被描述为具有集体缓冲和数据筛选的两阶段I/O[53, 199]。这种优化实际上改变了应用程序发出其I/O请求的方式,即改变了其访问模式。

图6:读请求的两阶段I/O。

集体缓冲旨在通过尽可能使文件访问更大更连续来减少I/O时间,即使这需要在秩之间进行额外的通信。在两阶段I/O中,聚合器进程负责执行写入和读取。每个聚合器从文件的一部分秩中管理一个连续数据块。在写入过程中,聚合器将来自一组秩的数据聚集到内存中的连续块,并将聚合后的数据写入文件系统。在读取时,聚合器加载文件的一部分,并将较小的数据块分配给一组秩,如图6所示。例如,ROMIO是MPI-IO的一种可移植高性能实现,它提供了两个用户定义的调整选项,可以控制这种技术的应用:在I/O阶段实际发出I/O请求的进程数量(cb_nodes),通常称为聚合器;和每个进程的最大缓冲区大小(cb_buffer_size)。这些选项有助于定义底层I/O堆栈感知到的访问模式。

数据筛选是MPI-IO中的另一种优化,旨在通过尽量减少对PFS的请求来降低I/O延迟。对于读取操作,当进程发出非连续请求时,ROMIO不是分别读取每个数据片段,而是将文件中从第一个请求字节到最后一个请求字节的一个连续块读入内存中的临时缓冲区。ROMIO提供了两个用户定义的参数来控制读取(ind_rd_buffer_size)和写入(ind_wr_buffer_size)的缓冲区大小[199]。如果用户请求的文件部分过大,超出了分配的内存,ROMIO实现将按照缓冲区大小划定的部分执行数据筛选。数据筛选的一个注意点是当访问中存在大的间隙时,这可能会超过读取额外数据的成本。

总结(4)
中间件层提供了应用优化技术的机会,以更适合底层文件系统的方式来转换数据。集体缓冲和数据筛选是MPI-IO中提供的两种解决方案,用于通过重新塑造I/O访问模式来改进数据访问。


6 文件系统层的访问模式

大规模的HPC系统使用并行文件系统(PFS)提供持久性的共享存储基础设施,如第2节所述。PFS部署在一组专用节点上,并提供共享的命名空间,使得应用程序可以无缝访问远程文件。它们通过将文件分成块或条带并将它们分布在多个存储节点上来利用并行性以实现高性能。这种操作通常称为数据条带化[188]。图7(a)说明了文件如何在多个存储服务器(在Lustre中称为对象存储目标OST)之间进行条带化。


图7:与文件分段相对齐和未对齐的并行文件系统的请求。

由于条带可以位于不同的存储目标中,为了完成写入/读取操作,PFS可能需要访问多个目标。不对齐的请求也可能需要访问多个OST来完成操作,并引入效率低下[105, 127, 238]的原因是错误数据共享。图7(b)描述了这种情况。例如,考虑一个应用程序向存储有64KB条带大小的文件发出64KB请求。如果文件的前136KB用于某些头部表示,那么所有的数据访问都会受到头部的影响。因此,PFS客户端需要将请求分开,例如在图7(b)中完成第二个请求(粉色部分),需要联系两个目标(OST 2和3)来访问文件条带的不连续区域以完成请求。可以很容易地推断出在更大范围上不对齐的请求的影响

此外,由于这种集中式共享基础设施,客户端要访问OST,它们需要通过网络进行通信,这可能会引入开销和争用,尤其是当请求大小较小且突发性较大时。前面的例子可能导致大量较小的请求(64KB)发出,因为不对齐。此外,对于文件系统服务器,连续的数据访问通常比非连续的访问(对于硬盘驱动器和固态硬盘而言)[231]产生更高的I/O性能。Zimmer等[242]等人证实,小而随机的请求模式对文件系统性能产生负面影响。因此,应用程序通过发出更少的请求访问文件时,会观察到减少高I/O延迟的好处。

讨论文件系统层的访问模式时,直接影响性能的另一个关键方面是元数据访问。在基于Unix的操作系统中,元数据存储在索引节点(i-node)中,包含有关所有权、权限、对象类型(例如文件或目录)、大小和修改时间戳的信息[170, 192]。此外,由于并行文件系统倾向于依赖POSIX I/O语义(它们并非针对并行访问而设计),因此元数据访问的可扩展性通常受到影响。例如,在一个单一目录中,由多个进程创建大量文件时,预期会发生串行化。这是HPC应用程序中经常观察到的一种模式[1, 13, 51, 205, 226]。

此外,由于这些并行文件系统倾向于采用数据条带化的概念(以允许并行访问并提高性能),在访问数据之前,PFS客户端必须从一个元数据服务器中获取权限并获得文件布局(包括条带位置和大小)的信息。在Lustre并行文件系统中,元数据服务(MDS)提供Lustre文件系统的索引或命名空间。元数据内容存储在称为元数据目标(MDT)的卷中。由于大多数基本操作都涉及元数据,因此确保元数据访问的可扩展性至关重要。例如,在Lustre 2.4之前,只能使用单个MDT存储元数据。Lustre 2.4版本引入了分布式命名空间(DNE)的概念,使元数据工作负载可以分布在多个MDT上,这些MDT通常分布在多个元数据服务器上。然而,与数据服务器相比,元数据服务器通常较少,如果没有集中到单个服务器中以避免复杂的缓存一致性问题和开销。不用说,创建或访问大量文件的应用程序可能会受到元数据的限制,并可能由于元数据服务器的共享特性而影响系统中的其它应用程序。

已提出了不同的方法[129, 145, 164, 166, 176, 221]来解决元数据问题,涵盖了如何高效处理、扩展和索引元数据。例如,Liao等人[129]提出了一种元数据管理系统,该系统使用数据库记录数据集的信息,并在提供合适的I/O接口的同时管理元数据。Paul等人[166]提出了一种针对大规模HPC存储系统的元数据索引和搜索工具。他们的解决方案依赖于使用树型设计和并行层次分区方法将文件系统命名空间划分为不相交的子树。他们维护一个内部的元数据索引数据库,该数据库使用2级数据库分片技术来提高索引和查询性能,结合基于changelog的方法来跟踪元数据更改并重新索引文件系统。Wu等人[221]提出了StageFS,这是一种针对基于SSD的集群进行优化的并行文件系统。StageFS将元数据和小文件都存储在LSM树中以实现快速索引。为了避免频繁的小写操作,StageFS使用缓冲以更好地利用SSD设备的带宽。与最先进的解决方案相比,他们展示了高达21.28倍的元数据操作性能改进。

由于这些存储部署的共享性质,多个同时运行的应用程序提交大量元数据操作,可能会轻松饱和共享PFS元数据资源。在这方面,Shafer等人[176]提出了MetaFS,旨在解决程序加载期间的元数据活动突发问题。它对应用程序的静态元数据内容进行索引,并将其以批量形式传递给执行节点,可以在那里缓存和查询,从而将元数据活动与数据传输进行交换。他们的方法观察到了共享文件系统上元数据负载的数量级降低。在同样的方向上,Macedo等人[145]提出了一种存储中间件,使系统管理员能够主动控制和确保HPC存储系统中元数据工作流的服务质量。他们的解决方案旨在避免饱和共享元数据资源,从而导致存储后端的无响应和整体性能下降。

总结(5)
由于其共享性质,一个并行文件系统会收到多个并发运行的应用程序的交叉请求。因此,这些存储目标所看到的I/O访问模式可能与应用程序最初发出的请求有所不同。此外,元数据请求在可扩展性和性能方面起着至关重要的作用,这是由于这些系统的集中特性所致。


7 访问模式分类

HPC应用程序按照其数据建模和编码的方式以不同的方式向文件系统发出I/O请求。它们还倾向于呈现一致的I/O行为,其中少数访问模式在长时间内被多次重复使用[35, 61, 62, 70, 89, 137]。对这些模式以及适用于每种模式的哪些优化的更好理解,可以提高应用程序端的性能,以及在考虑整个系统时的性能。基于此,一些特征可以一起用于描述应用程序的访问模式。虽然没有全球公认的约定来描述哪些元素或特征定义访问模式,HPC I/O领域的研究人员通常会考察一组常见的因素或参数。例如,文件处理方式(单文件或共享文件)、请求数量、请求大小以及文件中的空间局部性[16, 34, 137, 138, 227]。然而,对于特定的应用程序或优化技术,也会考虑其它特征,比如时间行为、强度或突发性以及重叠访问[16, 61, 187, 214, 228, 229, 234]。访问模式确实对实现的性能产生直接影响,这解释了为什么不同的研究工作投入到了优化数据访问中[30, 81, 115, 138, 231]。

图8:用于在HPC I/O软件栈的不同层次描述I/O访问模式的特性分类:应用程序侧、高级I/O库、中间件层和文件系统。一些特性因其跨栈层次的重要性而重复,而其他特性则固有于特定层次。第7.2节根据多年来的社区使用对这些特性进行了分组。

我们希望提供一个基于业界共识和长期使用的I/O访问模式分类法。我们认为这种形式化对科学界是有帮助的,因为应用程序经常观察到I/O性能差,原因是系统中的瓶颈可能是指标收集、瓶颈检测和优化解决方案之间的缺乏转化。一个明确定义且广泛接受的分类法将有助于将指标转化为模式,并指导最终用户如何利用各种现有的优化技术来改善I/O应用程序性能。图8使用节点链接的分层树状图在极坐标中描述了来自HPC I/O堆栈不同层次的类的分类法。

此外,除了每个层次中使用的特征之外,还可以从不同的范围观察I/O访问模式。Yin等人[231]将访问模式分类为本地、全局或系统级。本地模式描述了进程或任务上下文中应用程序的行为,而全局模式则描述了在应用程序级别上的行为,考虑了所有进程和任务。另一方面,系统级模式描述了使用共享存储基础设施或I/O节点时不同并发应用程序的模式。本地访问模式信息通常用于识别和应用客户端端的优化。相反,全局访问模式更适合于I/O中间件、转发层或文件系统服务器,因为它对应用程序的数据访问有全面的了解。系统级访问模式也可以在数据服务器[23, 118, 169, 187, 236]和转发层[2, 16, 20, 159, 232]中用于协调访问和优化整个系统的I/O性能。

7.1 访问模式特征

在本节中,我们将讨论用于描述I/O访问模式的常用特征以及它们在I/O堆栈中的使用方式。我们将模式分类为基于I/O操作、同步性、文件处理方式、空间局部性、接口、一致性和时间行为。

7.1.1 操作

我们可以广泛地将I/O操作分类为写入和读取。对于附加操作,文件偏移量首先通过寻位操作定位在文件末尾,然后写操作将数据附加在文件上。文件偏移量的修改和写操作作为单个原子步骤执行。

7.1.2 文件处理方式

执行并行I/O的情况有多种,取决于有多少进程(MPI ranks)正在执行I/O,以及有多少个文件被进程访问。在第一种情况下,应用程序的每个进程将其操作发出到单独的文件,这称为文件-每-进程方式,如图9(a)所示。此情况由多个文件和多个写入者/读取者表示。当进程数太多时,可以将数据聚合到一小部分进程中,并且它们可以访问较少的文件。这称为子文件方式[28, 29]。尽管通过利用多个数据服务器继承的并行性,可能会实现性能的提升,但将来用于后处理或分析的数据将不得不访问这些多个文件来获取所需的数据,因为它是分散的。处理极大规模应用的元数据操作时,该方法的可扩展性受到限制。

图9:文件数和读/写数量。

在第二种情况下,所有进程共享一个共同的文件(共享文件)。我们可以根据写入者的数量进一步区分这种情况。在与文件-每-进程相对立的极端情况下,单个写入者(通常为rank 0)接收来自许多或所有rank的数据(通常使用集体MPI调用),重新排列数据,并将其写入单个共享文件,如图9(b)所示。这种方法的性能受限于聚合节点中可用的内存(用于接收和处理整个应用程序的数据),此外,它无法有效地利用到存储服务器的总可用带宽。我们可以有一组排列和发出I/O操作的rank的子集,如图9(d)所示。这种策略意味着每个rank与其聚合器之间进行通信,后者在将请求发送给存储系统之前还要进行额外的数据重新排列步骤。最后,另一种已知的方法是让所有rank将其数据写入文件的预定义非重叠位置,避免了rank之间的通信,而是依靠隐式协调,如图9(c)所示。这种方法的性能也受限,因为在同一计算节点上的rank之间没有I/O请求的协调或聚合。

7.1.3 空间局部性

空间局部性是指连续I/O访问之间的文件偏移。典型的空间访问模式包括连续、步进和随机。这个特性直接影响I/O性能,因为存储基础设施(在硬件和软件层面)受到请求的顺序性影响[21]。例如,文件系统可以在预测到正则模式时缓存或预取数据,以避免连续I/O请求之间的昂贵寻位操作,从而提高HPC应用程序的I/O性能。

图10:文件中I/O请求的空间局部性。

我们可以通过I/O请求的文件偏移和大小来定义其空间局部性,其中表示第h个请求。如果对文件的访问是顺序的,每个进程访问文件的连续块(图10(a)),并且对所有后续请求,关系式,+1 = , + ,都成立。另一方面,在步进(1D、2D、D)模式中,每个进程访问数据的部分,它们之间有固定大小的间隔(或步幅)(图10(b))。文件指针在每个请求之间增加相同的量(即步幅),因此, ,+1 = , + ,其中 = Í ,通常是一个常数。此外,当访问共享文件时,步进访问是常见的。对于每个进程的文件方式,文件通常是连续访问的。尽管对于传统的HPC来说,随机访问(图10(c))较少见[177],但机器学习应用的新型工作负载经常表现出这种行为[43, 55, 240, 241],这往往是由于在迭代和周期之间对数据进行洗牌,通常导致大量并发数据写入文件系统。

7.1.4 接口

接口旨在提供一种方便且易于使用的方式来访问资源。在I/O的上下文中,这些接口在访问文件(本地或远程)时具有重要作用,通过定义API和语义来实现。此外,在HPC中,这些接口应该努力在可用性和高性能之间取得平衡,这通常是相互矛盾的目标。我们可以考虑三个主要的接口,这些接口由应用程序或高级库直接使用来表示其访问模式:POSIX I/O、MPI-IO和STDIO。高级I/O库提供各种API,简化了应用程序级别与MPI-IO和POSIX接口之间的数据模型映射。例如,HDF5使用MPI-IO接口进行并行I/O,使用POSIX-IO进行顺序应用程序的I/O。ADIOS和PnetCDF也类似地使用MPI-IO和POSIX。以下简要讨论每个接口,并在表2中总结它们在HPC背景下的机会和挑战。

表2:在HPC背景下使用每个I/O接口时的机会和挑战。

POSIX I/O:可移植操作系统接口(POSIX)是IEEE定义的一组标准,用于在各种操作系统之间保持兼容性,允许应用程序从操作系统获取基本服务。POSIX还定义了用于与文件系统交互的I/O API。其I/O接口最初在1988年的POSIX.1规范中引入,并且旨在支持本地文件系统访问。POSIX.1b [92]引入了异步和同步行为。尽管它是为支持顺序应用的本地文件系统而设计的,但由于其可移植性,POSIX被广泛应用于各种应用中。

然而,当在HPC中使用时,POSIX的可移植性是有代价的。POSIX语义定义了在使用其API时保证什么和不保证什么。例如,它规定写操作必须是强一致性的,即必须在写入数据后阻塞应用程序执行,直到系统能够保证任何后续的读操作实际上都读取了刚刚写入的数据。对于HPC,这些严格的要求为分布式和并行文件系统引入了复杂性,其中远程进程不知道本地进程可能在文件中进行修改,反之亦然。HPC中心通常提供基于POSIX的并行文件系统(例如Lustre和GPFS),它们遵循强一致性语义,强制进行顺序访问[209]。所需的语义要求许多并行文件系统实施分布式锁机制以确保一致性,从而对大规模的I/O访问造成惩罚。然而,现代HPC应用通常不需要如此强的一致性保证[132, 209]。

由于POSIX并不是专门为HPC应用设计的,它可能对最终用户造成负担。例如,可以使用共享文件并行I/O方法。但是,并行访问、缓冲和冲洗的复杂性都被明确地委托给最终用户。此外,由于文件被视为不透明的字节流,应用程序无法向文件系统表示或提示其数据的组织方式。这样的信息对于数据布置策略和优化是至关重要的。例如,MPI-IO接口使用此类信息来表示复杂的访问并实现高性能。然而,有一些努力试图扩展POSIX I/O以满足HPC的需求。Vilayannur等人[206]设计了一个建议的POSIX扩展,以支持共享文件描述符/组开放、惰性元数据属性、非连续读/写接口和批量元数据操作。这些努力尚未集成到主要的存储解决方案中。

MPI-IO:另一方面,MPI-IO [68]被提出作为MPI标准的扩展,通过重用MPI的消息传递概念来定义I/O操作。写入文件就像发送消息一样,从文件读取就像接收消息一样。MPI-IO提供了一个高级接口,用于描述进程之间的数据分区,以及一个集合接口,用于描述进程内存和文件之间的全局数据结构之间的传输。此外,它支持异步I/O操作。因此,MPI-IO允许计算与I/O重叠,并在存储设备上优化物理文件布局[47]。此外,MPI-IO的语义与POSIX不同,放松了一些一致性要求,同时为依赖于更严格语义的应用程序提供原子模式。

为了表达应用程序天然的灵活I/O访问模式,MPI-IO依赖于MPI导出的数据类型。这些类型用于表示数据在内存中和文件中的布局。此外,数据访问在MPI-IO中具有三个正交特性:定位(显式偏移或隐式文件指针)、同步(阻塞或非阻塞)和协调(独立或集合)。所有这些特性都使用文件指针(个别或共享)来表示。

MPI-IO接口是在名为ADIO [198]的并行I/O的可移植抽象设备接口之上实现的,它可以针对各种文件系统进行优化。ADIO本身不是用于应用程序员直接使用的,而是用作某些其它用户级I/O接口实现的内部接口。例如,ROMIO [201]是MPI-IO的高性能、可移植实现,专门用于非连续访问模式,这在并行应用中很常见。它依赖于ADIO的可移植性,可与任何MPI实现一起使用(ROMIO通常作为多个MPI实现的一部分包含,如MPICH、Cray MPI和OpenMPI)。

由于MPI-IO在POSIX之上构建,它生成复杂的I/O访问模式。由于优化和转换(例如集体缓冲和数据筛选[53, 199])会导致请求穿越I/O堆栈时,最终到达文件系统的模式可能与最初在科学应用代码中表达的模式大相径庭。

STDIO:标准I/O库(STDIO)提供了一个简单的、带缓冲的流I/O接口。它将所有文件操作抽象成字节流的操作。STDIO包含C stdio.h系列函数[97],例如fopen、fprintf和fscanf。但是,STDIO函数不直接支持对数据的随机访问。在这种情况下,应用程序必须打开一个流,寻找文件中所需的位置,然后从流中按顺序写入/读取字节。

最近,STDIO在HPC工作负载中越来越受欢迎[144, 182],特别是对于依赖I/O函数以文本格式存储序列信息的基因组学和生物学生产应用。对超级计算设施的跟踪分析表明,STDIO在超级计算机平台上的使用越来越多,并且在各种科学领域中得到广泛应用[17]。研究还发现,尽管STDIO对于某些传输大小可以获得高带宽,但在Cori(NERSC)和Summit(OLCF)超级计算机上,它在各种传输大小上始终提供比POSIX低的性能,表明整体I/O性能较差。

7.1.5 I/O模式

I/O模式指的是并行进程(MPI进程)如何访问文件:每个进程独立访问,或者由部分进程集体访问。集体操作在接口(如MPI-I/O)中很容易实现,这些操作提供了所有进程共同打开同一文件的整体数据移动情况。这些函数要求所有集体打开同一文件的进程都参与调用,因此允许优化(如集体缓冲和数据筛选[199])来通过构建更大和连续的访问来提高性能,从而提高底层存储系统的I/O性能。

I/O模式可以直接改变在使用集体操作时底层层次感知到的访问模式。在集体I/O调用中,目标为聚合文件访问区域被划分为非重叠区域(文件区域),由聚合器将其发送到通信阶段中,所有进程根据其文件域向聚合器发送I/O请求。在I/O阶段,聚合器将请求提交给系统。因此,聚合器在传递给POSIX层或文件系统之前有效地将请求合并为更大和连续的请求。

7.1.6 同步性

同步或阻塞I/O例程在I/O操作完成之前不会返回成功。另一方面,异步或非阻塞I/O操作允许应用程序通过将I/O操作与计算或通信步骤重叠来隐藏相关成本,从而推动应用程序的进展。后者在科学应用中变得越来越受欢迎,以访问大量数据并提高用户感知的性能。POSIX和MPI-IO提供了异步API来从文件中写入和读取数据。POSIX标准提供aio_调用,而MPI-IO具有MPI_File_i调用,用于独立和集体I/O操作。一些高级I/O库,例如ADIOS和HDF5,也提供了这些非阻塞接口[195]。相比之下,数据管理系统(如Proactive Data Containers(PDC)[194])通过网络数据传输向其服务器节点提供异步数据移动。新颖的对象存储文件系统,例如分布式异步对象存储(DAOS)[124],是围绕异步概念构建的,以提供性能。

7.1.7 时间行为

为了自动检测性能不佳的HPC作业,Buneci和Reed [27]从时间序列指标中生成包含性能特征的时间签名,将应用程序分组为两组:表现如预期的组和表现不如预期的组。他们将用户提供的高级状态与之前的执行基础上的低级指标相结合,以检测影响性能的因素。尽管他们的方法使用两个I/O指标来构建签名,但他们并不专注于此,而是专注于CPU、内存、磁盘和网络使用的组合。Dorier等人[61,62]提出了Omnisc’IO,它构建了基于语法的任何HPC应用程序I/O行为,以预测未来的使用。他们试图预测I/O操作何时发生,即请求之间的到达时间间隔以及将访问多少数据,包括文件中的偏移和大小。为了进行与时间相关的预测,Omnisc’IO存储统计数据,如最小和最大观察到的请求之间的时间、平均值和方差,并依靠加权到达平均时间来对变化做出反应。根据这些数据,他们可以预测下一个操作是否会在可预测的时间内立即跟随当前操作,以及下一个操作之前的时间是否更不可预测。

另一方面,White等人[219]将特别关注I/O,提出了HPC作业时间I/O模式的分类学,以帮助自动检测性能不佳的作业。他们描述了一个简单的启发式分类算法的设计,该算法根据I/O的大多数发生时间进行作业分类。作者观察到少数常见的I/O访问模式:主要I/O使用在作业开始时,主要I/O使用在作业结束时,I/O活动在开始和结束时发生,但在作业过程中没有,开始或结束时I/O较少,但在中间较多,整个作业中有规律的活动和定期I/O活动。

7.1.8 一致性

在检查重叠的I/O模式时,Wang等人[211]考虑了I/O操作的一致性。他们试图理解进程是否会多次写入/读取文件的同一部分,是否有多个进程写入/读取文件的同一部分,以及操作在给定偏移处发生的顺序。为此,他们考虑了Read After Read(RAR),Write After Write(WAW),Read After Write(RAW)和Write After Read(WAR)等指标来构成模式。应用程序使用的一致性策略还有助于确定缓存技术是否可行。

7.2 业界使用调查

图11. 本次调查中使用的ACM DL查询和筛选参数。

图12:本调查中使用的IEEE Xplore查询和筛选参数。

为了了解广泛的HPC业界如何处理和描述其应用的I/O访问模式,我们过滤了ACM Digital Library1和IEEE Xplore Digital Library2,考虑了一个20年的窗口,涵盖了2000年到2021年之间提到“I/O访问模式”、“I/O特性”、“I/O特征”或“I/O签名”的出版物。文本还应该涉及到这些术语中的任何一个“HPC”。在过滤会议和期刊出版物后,在ACM中得到74个结果,在IEEE中得到161个结果。在图11和图12中,我们分别展示了在ACM DL和IEEE Xplore中使用的查询。我们根据作者用于描述多个I/O层次的I/O访问模式的特征,将这些论文分类,如图13所示。

图13:ACM DL和IEEE Xplore研究论文中描述I/O访问模式的特性、接口和库。

我们的方法是在整个文本中寻找常见的预定义关键词,这些关键词用于描述每个I/O访问模式特征。每篇论文都经过预过滤和手动检查,以避免误报。我们定义了一组标签,对应于每个特征及其使用情况。由于选择方法和术语在相关领域(如内存)中的广泛使用,一些选择的论文实际上与本调查无关。因此,它们后来被排除在分析之外。最后,我们考虑了146篇论文,用于本节所述的分析(占235个结果的62.13%)。具体而言,我们使用以下标准过滤了初始论文集。

  •  关键词应在实验中或在提出的技术或解决方案中使用;

  •  仅仅引用或使用关键词并不使论文归入该分类(例如,提到HDF5作为IOR的接口并不意味着它属于HDF5类别,除非它在评估中使用);

  •  如果该特征仅用于描述不相关的工作,那么论文不会被标记在该类别中;

  •  这些关键词的定义被重载以描述I/O领域之外的特征,例如内存、通信或计算(例如,同步/异步)。在这种情况下,它们在I/O访问模式的上下文中被视为不相关;

  •  为了避免分类偏见,如果作者没有明确说明某个特征,我们认为他们没有考虑到(除非从上下文中明显可见);如果存在疑问,我们会假设它没有被使用。

在图13中,我们总结了我们的发现。在讨论访问模式时,122篇论文(即83.56%)涵盖了数据操作,而只有48篇论文(即32.89%)考虑了元数据操作。然而,这些论文没有详细描述其元数据I/O模式。关于特征,操作(96.57%)、请求大小(67.81%)和空间局部性(65.07%)是绝大多数研究论文考虑的特征。尽管文件访问方式与空间局部性密切相关,但58.90%的调查论文并未明确讨论文件访问方式。集体性和同步性是讨论或描述访问模式时较少关注的特征,这两者都与I/O优化技术有关。

图14:在ACM DL和IEEE Xplore研究论文中用于描述I/O访问模式的特性集的分析。

在图14中,我们描绘了调查研究论文中使用的特征的交集集合,考虑了图13中详细描述的七个特征。为了总结所有交集及其分布,我们依赖于UpSet图,这是一种用于定量分析交集集合及其属性的最新可视化技术[45,120]。从中可以清楚地看出,不是所有相关特征都被正确描述和考虑在大多数工作中,哪些特征通常一起考虑(例如,操作、请求大小和空间局部性)。表3将这些不同的特征映射到相应的工作,并引用这些工作,以便读者可以找到有关如何在不同情况和科学领域中应用这些特征的详细信息。

表3:根据其讨论I/O访问模式时使用的特性,将ACM DL和IEEE Xplore调查论文进行分组。

我们还根据论文使用的接口和高级库将研究论文进行了分组。在接口方面,大多数论文(57.53%)在实验中使用MPI-IO,并明确考虑了该接口在讨论所提出的解决方案或优化技术的适用性时。其次是POSIX,占47.26%,而STDIO仅有3.42%的调查论文。另一方面,Bez等人[18]强调在Summit(OLCF)和Cori(NERSC)超级计算机上广泛使用STDIO,涵盖了广泛的科学领域,这表明由于从传统的数值模拟转向AI/ML应用以进行训练和推断,处理和产生日益增长的科学数据,这可能是一种新的趋势。关于高级库,大多数论文并未明确承认使用特定的库,尽管HDF5被使用了27.40%。

总结(6)
业界一直使用共同的特征(例如操作、大小和空间性)来描述I/O访问模式,同时根据目标层或优化环境提供附加信息。此外,元数据访问通常没有像数据访问那样详细地描述。


8 测试I/O访问模式

本节简要介绍现有的基准测试和I/O内核,这些工具经常用于科学I/O研究,以测试访问模式。我们描述了基准测试用于表示I/O访问的特征,以及不同科学应用内核的I/O工作负载特性。

表4:每个基准和I/O内核所使用的访问模式特性的总结。橙色的勾表示h5bench确实支持异步操作,但需要HDF5 ASYNC VOL Connector [195]可用和启用。

表4总结了由业界用于测试不同数据工作负载下的HPC I/O栈的基准测试和I/O内核。我们根据它们的表示方式(纯合成工作负载还是作为应用程序的代表性I/O内核提取出来)、重点(数据或元数据)、操作(写入或读取)、支持请求大小、模式(独立或集体操作)、时间行为、文件方法(共享文件或每进程文件)、同步性(同步或异步请求)对工具进行了分组。我们还描述了支持的I/O接口。

IOR [88] 是一个I/O基准测试,用于测试使用各种接口和访问模式的并行存储系统的性能。它支持不同的接口或API(POSIX,MPI-IO,HDF5,HDFS,S3,NCMPI,IME,MMAP或RADOS)。IOR足够灵活,可以通过配置操作、每个任务写入的连续字节(块大小)、传输大小、段数,以及是否使用集体或个体操作(适用的情况下),以及每个任务是写入自己的文件还是共享文件来表示模式。

MADbench2 [25] 是从MADspec应用程序中提取的I/O内核。MADbench2允许在真实科学应用的压力下测试大规模并行架构的I/O、通信和计算子系统的集成性能。它直接从大规模宇宙微波背景(CMB)数据分析包中导出。它计算CMB辐射的最大似然角功率谱,从带噪声的像素化天空图和其像素-像素噪声相关矩阵中。MADbench2有一个常规模式,在该模式下执行全部代码,以及一个I/O模式,在该模式下,所有计算/通信都被忙碌的工作替代。内核有三个组件函数,每个函数具有不同的访问模式,分别命名为S、W和C。在S中,每个进程写入2个字节。在W中,每个进程读取2个字节并将其写入/进程。在C中,每个进程读取2/字节,其中定义了进程数,并设置了伪数据的大小,所有组件矩阵都有×个元素。设置了由组件矩阵组成的伪数据集的大小。最后,设置了团队并行性的级别,允许MADbench2作为单一或多个团队运行。在前者中,所有矩阵操作都在所有处理器上分布执行。该内核可以使用POSIX或MPI-IO接口,以同步或异步方式发出I/O操作,写入唯一文件或共享文件。

IFER是类似于IOR的微基准,但其目的是提供有关I/O争用的见解。它将进程分为两组,在两组不同的节点上运行,以模拟两个竞争应用程序。每个进程组根据预定义的模式执行一系列集体I/O操作。虽然IFER仅支持将写请求发送到共享文件,但它考虑了两种模式:连续模式和一维跨距模式。IFER还依赖于两个附加参数,块大小代表每个进程写入的连续字节,块计数代表在连续模式下每个进程将持续写入的块数。对于跨距模式,块根据其偏移在文件中分布。因为它的最初目标是研究I/O干扰,IFER允许用户定义I/O阶段之间的到达时间。

S3D I/O内核[39] 是一个连续尺度的第一原理直接数值模拟代码,解决质量连续性、动量、能量和化学物种质量分数的可压缩控制方程,包括化学反应。它在固定间隔创建检查点,其中将三维和四维的double数组写入新创建的文件。所有三维数组在MPI进程之间使用所有 - 维度的块划分,而第四维(最重要的维度)不被划分。该内核可以配置为使用PnetCDF的阻塞或非阻塞API。对于后者,一个检查点有四个非阻塞写调用,每个变量一个,然后调用wait和flush来写请求[128]。

NAS BT-IO [155] 是基于NAS Parallel Benchmarks (NPB)的Block-Tridiagonal (BT)问题的基准测试。每个进程负责数据集的多个笛卡尔子集,其数量随着参与计算的进程数量的平方根增加。整个解决方案,每个网格点由五个双精度数据组成,必须在每五个时间步骤时写入文件。最后,属于单个时间步长的所有数据必须存储在同一个文件中,并按照矢量组件,即,和坐标进行排序。

S3aSim [42] 是基于序列相似性搜索框架的I/O内核。它使用主从并行编程模型和数据库分段,模仿了mpiBLAST [52] 的访问模式。给定输入查询序列,S3aSim将数据库序列划分为片段。工作进程从主节点请求查询和片段信息,并将查询与分配的数据库片段进行匹配。结果发送到主节点进行排序,然后写入一个单一的共享文件。在每个查询之后没有同步,该应用程序使用独立的I/O操作将数据写入单个共享文件。

Parallel I/O Kernels (https://github.com/hpc-io/PIOK) 提供了使用HDF5的各种科学模拟代码的并行I/O部分。这些内核已通过h5bench扩展,以涵盖各种HDF5 I/O模式。h5bench [122] 是一组HDF5 I/O内核,代表HPC系统上常用的HDF5应用程序中常见的I/O模式。它提供了一个框架,用于测试、运行和调整I/O性能,使用HDF5引入的新特性,并了解该库在不同机器上在此类I/O工作负载下的性能。它从多个方面测量I/O性能,包括原始和观察到的I/O时间和速率。

HACC-IO [207] 是从HACC(硬件加速宇宙学代码)宇宙学框架(Gordon Bell奖提名者 2012, 2013)中提取的内核。它使用N-body来模拟受重力影响的无碰撞流体。该内核包括模拟产生的检查点、重启和分析输出。因此,它的I/O负载相当大。它还支持POSIX和MPI-IO(带有独立和集体操作)接口。关于文件方法,HACC-IO可以配置为写入单个共享文件,每个进程一个文件,或两者的混合(即,每组一个文件)。它仅需要输入参数粒子的数量(),其中每个粒子由七个4字节浮点数、一个8字节整数和一个2字节整数组成。因此,每个进程写入/读取 × 38字节。

MACSio(多用途,应用中心,可扩展的I/O代理应用)[151] 用于I/O性能测试和评估数据模型、I/O库接口和多物理、HPC应用的并行I/O范式中的权衡。它与其它基准测试的不同之处在于,它实际上将数据构造和组织成科学计算应用程序中常用的真实数据对象。因此,MACSio可以密切模拟多物理领域的I/O工作负载,其中数据对象的分布和组成在并行进程内和之间变化。它还支持使用多种文件方法来表示数据(分段和跨距的单个共享文件,多个独立文件或每进程一个文件),并支持独立和集体操作。

MPI Tile I/O [171] 是一个适用于测试底层MPI-IO和文件系统实现在非连续访问工作负载下性能的基准测试。它将数据文件逻辑地划分为密集的二维瓷砖集,基于和维度中的瓷砖数。它允许最终用户配置每个瓷砖维度中的元素数量和元素大小。它可以通过定义在每个维度中相邻瓷砖之间共享的元素数量来表示重叠元素。MPI Tile I/O 支持集体I/O,允许对参与聚合的节点列表进行微调。

为了模拟在HPC系统上越来越流行的科学深度学习工作负载,DLIO [55] 提供了一个I/O基准测试套件。DLIO支持各种科学深度学习应用,包括使用UNet的中微子和宇宙标记、分布式洪水填充网络(FFN)、卷积神经网络(CNN)、用于宇宙学数据集的CosmoFlow、融合循环神经网络(FRNN)和癌症分布式学习环境(CANDLE)。DLIO允许从不同的文件格式和API(如HDF5、CSV和TFRecord格式)中读取数据。

总结(7)
业界提供了大量的基准测试和I/O内核,用于测试栈的不同层次上的访问模式。没有一个基准测试涵盖所有特性,但它们结合起来覆盖了不同的特性、接口和应用程序数据模


9 I/O访问模式的性能分析和可视化

Darshan [34] 是一种常用的工具,以轻量级的方式收集应用程序的I/O性能分析信息。Darshan聚合I/O分析信息,提供有价值的见解,同时不会增加额外开销或扰乱应用程序的行为。它还提供了一个扩展跟踪模块(DXT) [223],以获取应用程序行为的细粒度视图,从而理解I/O性能问题。一旦启用,DXT会收集来自POSIX和MPI-IO层的详细跟踪,报告每个请求的操作(写入/读取)、发出调用的进程、段、文件中的偏移量和每个请求的大小。它还捕获每个进程发出的所有操作的开始和结束时间戳。

Recorder [211] 是一个多级I/O跟踪框架,可以在I/O栈的多个级别捕获I/O函数调用,包括HDF5、MPI-IO和POSIX I/O。作为一个共享库,它不需要对应用程序进行修改或重新编译,并允许用户控制跟踪级别。Recorder使用函数拦截来拦截I/O调用,从而捕获时间戳、函数名和所有参数。

Tuning and Analysis Utilities (TAU) [178] 是一个集成的性能仪器、测量和分析工具包。它可以捕获文件I/O(串行和并行)、通信、内存和CPU的性能数据。关于I/O,TAU可以处理性能分析和跟踪,观察包括(包括所有子区域)和排除(仅针对区域)测量。它使用库包装来表征I/O性能,这有助于自动化对外部I/O包和库的仪器化。因此,TAU可以捕获POSIX和MPI-IO,并仪器化HDF5等库。

IOPin [107] 提出了一种动态仪器化框架,以了解应用程序到底层PFS的不同I/O层之间的复杂交互。它利用Pin轻量级二进制仪器化的探测模式来仪器化应用程序和I/O栈的组件,为并行I/O提供层次化视图。他们的实现支持MPI库和PVFS。他们的方法仅跟踪和仪器化由Pin识别为具有最大I/O延迟的进程。这种动态指令降低了开销,并集中于检测在栈中影响性能的关键I/O路径。IOPin提供的指标包括延迟、磁盘吞吐量、客户端到服务器的请求数量以及每个请求的磁盘访问次数。然而,它不提供每个I/O请求的特征描述。

ScalaIOTrace [142] 是一个基于ScalaTrace [158] 的多级I/O跟踪工具,后者是用于并行应用程序的MPI通信跟踪框架。ScalaIOTrace支持MPI-IO和POSIX-IO互操作。MPI-IO跟踪依赖于MPI性能分析层(PMPI)来拦截和收集MPI调用。同时,POSIX通过使用GNUlink时间入口互操作包装器来捕获,该方法与PMPI类似,使用了领域特定的参数压缩。这个跟踪工具捕获I/O事件作为单例、向量和规则的节描述符来描述应用程序行为。这些数据被存储在一个单一、无损和保持顺序的跟踪文件中。他们的目标是生成一个可以推断出节点目标大小并重播以确认I/O可扩展性的跟踪。

Score-P [110] 是一个用于对HPC应用程序进行性能分析和事件跟踪的测量工具套件。通过在代码中插入测量探针,用户可以收集与性能相关的数据,这些探针在串行执行、OpenMP或MPI并行性或混合组合时由几个提供的运行时库触发。它还允许在性能分析和跟踪模式下进行选择性过滤,以限制记录到特定区域。对于输入和输出操作,Score-P可以收集POSIX-IO(例如,open/close)、POSIX异步I/O(例如,aio_read/aio_write)、STDIO(例如,fopen/fclose)和MPI-IO调用的数据。可以使用Periscope [12]、Scalasca [73]、TAU [154]和Vampir [109]来可视化Score-P输出文件。Periscope是一个在线性能分析工具,用于评估性能属性和测试关于典型性能问题的假设。Scalasca允许对事件跟踪进行事后分析,并自动检测性能关键情况。也可以使用TAU可视化工具集来相关Score-P或Vampir收集的性能数据,TAU作为事后交互式事件跟踪可视化软件。

DXT Explorer [19] 是一个交互式基于Web的日志分析工具,用于可视化Darshan DXT跟踪,并帮助理解应用程序的I/O行为。该工具为Darshan跟踪分析添加了一个交互式组件,可以帮助研究人员、开发人员和最终用户对应用程序的I/O行为进行视觉检查,放大感兴趣的区域,并清晰地了解I/O问题的位置。

在第3节中讨论了应用程序发出的I/O请求与中间层和文件系统实际感知到的不同之处。为了说明应用程序的I/O请求在穿过堆栈时所经历的转换,我们使用Darshan跟踪和DXT Explorer来可视化不同层次上的I/O访问模式。

图15:使用DXT Explorer的两个并行IOR实例。我们将访问模式从高级库(HDF5)描绘到它们到达POSIX层和Lustre中的底层对象存储目标(OST)的转换。

图16:两个并发IOR实例(一个以红色读取,另一个以蓝色读取)的I/O请求在每个Lustre存储服务器中到达的情况。我们放大了图15中报告的实验的前两秒。

图15描述了这样的转换。在这个实验中,我们有两个IOR实例(一个为红色,另一个为蓝色)。我们在两组不重叠的16个计算节点上分别执行了每个IOR实例,每个节点有8个进程,总共有128个进程。我们配置IOR以使用HDF5 API和集体MPI操作将一个32MB块大小的段写入共享文件中的十次迭代,每次传输大小为4MB。这两个实例同时启动。我们使用Darshan收集了配置文件和跟踪数据。由于Darshan Extended Tracing尚未捕获关于高级库(如HDF5)的细粒度信息,我们依靠手动仪器化代码,在执行写操作之前和数据集完全写入给定文件后收集时间戳。我们将两个图中的每个小图分解为所有进程共同发出的MPI-IO层的I/O调用。我们用星号符号在y轴上表示这些集体调用。

就应用程序而言,它在内存中的数据是由HDF5表示的1D数据集。HDF5将根据起始偏移量、计数、步长和块来访问数据。一个hyperslab表示数据集的一部分,可以是数据空间中逻辑连续的点的集合,也可以是数据空间中点或块的规则模式。在我们的实验中,对于共享文件,IOR将起始偏移量定义为offset模segmentSize,计数为1,步长和块等于传输大小,即4MB。然而,一旦请求到达MPI-IO层,它们会被四个集体聚合器进一步分解成更多的1MB POSIX请求,考虑到在将它们发送到每个存储设备之前的底层并行文件系统条带配置。我们已将Lustre定义为使用8个服务器上的1MB条带,以便更容易可视化。一旦我们深入到I/O堆栈的较低级别,我们就会丢失应用程序的上下文信息,并开始观察到这种共享存储基础设施中的自然干扰效应。例如,如果我们观察一个OST,请求以交错的方式到达存储服务器,来自文件系统不知情的两个应用程序。此时,应用程序发出的原始连续请求(使用4MB请求)以较小的方式(1MB请求)到达服务器,并具有不同的空间特性(非连续)。

此外,需要强调的是由其它共享数据服务器上的应用程序引起的跨应用干扰。图15清楚地展示了同时启动的两个相同应用程序在实验结束时开始出现差异的情况。这样的观察还突显了在讨论访问模式时考虑时间特性的重要性。

总结(8)
不同的工具从粗粒度分析器到细粒度跟踪中提取和可视化I/O访问模式,当I/O请求通过堆栈时。然而,我们未找到一个完整的解决方案,允许在每一层的上下文中观察模式及其所有的转换。由于当前堆栈的复杂性,这个空白可能不容易反映瓶颈的根本原因。


10 结论

由于硬件和软件的多层次结构、它们的各种调优选项以及层之间的相互依赖关系,HPC I/O堆栈变得复杂。本调查详细讨论了过载的“I/O访问模式”术语,用于描述HPC I/O堆栈的主要层次从不同角度进行访问的方式,涵盖了科学应用程序使用的高级模型,以及这些模型如何由高级I/O库表示并由中间件库转换后达到并行文件系统。我们还强调了用于在不同层次上练习访问模式的I/O基准和内核,以及使用分析和跟踪来可视化这些模式的现有工具。

借助过去20年来I/O业界的知识,我们从ACM DL和IEEE Xplore中调查了146篇论文,提出了一个基准分类法,可以定义应用程序的I/O访问模式。我们的努力旨在通过年复一年业界已经使用的特征,为描述模式的不同方式带来共识,为最终用户、应用程序开发人员和系统管理员在讨论、提出和应用I/O调优策略以改善I/O性能时提供一个共同的基础。

此外,现有的I/O堆栈暴露了大量的可调参数,并且支持不同的、通常是互补的优化技术来提高性能。然而,对于开发人员和最终用户来说,如何何时应用这些参数几乎没有指导。除了缺乏知识表明这些选项可用,并且在特定的访问模式集合中可能有所帮助之外,还没有一套定义调优参数的指导。要制定出一套最佳实践的清单,即使对于单个系统也是具有挑战性的,因为有许多因素影响着I/O性能。最后,没有一个共同的基础来识别和指称访问模式可能会增加复杂性,并且难以将I/O访问模式映射到其性能行为,然后再到优化策略。

随着HPC平台变得越来越复杂和专门化,以托管从机器学习到科学工作流的新型应用程序,对于那些寻求在运行时自动调整其参数的系统来说,准确检测I/O访问模式变得非常重要。建立一个分类法可以帮助弥合度量收集、访问模式表示和应用基于AI的自动调优机制之间的差距,以在观察到的应用负载上寻找优化和配置。

因此,尽管已经有了收集I/O性能配置文件和指标的工具,以及可以用于描述HPC I/O堆栈不同层次上的应用程序访问模式的特征,但在可视化和理解应用程序的行为、识别瓶颈并正确重塑其模式以在系统中获得更好性能方面仍然存在差距。报告和根据观察到的模式自动映射性能问题为可行操作,需要创新工具、模型和进一步的研发。


---【本文完】---

期受欢迎的文章:


我们正处于数十年未见之大机遇中

新技术爆发式发展,催生新产

然而,颠覆式创新并非简单的技术堆叠

而是异常复杂的系统工程

需要深度洞察

欢迎一起分享思考和见解

继续滑动看下一个
向上滑动看下一个

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存