读论文《SpecPMT: Speculative Logging for Resolving Crash Consistency Overhead of Persistent Memory》

SpecPMT: Speculative Logging for Resolving Crash Consistency Overhead of Persistent Memory

​ SpecPMT:用于解决持久性内存崩溃一致性开销的推测日志

华中科技大学

摘要

​ 在实际应用中**,崩溃一致性开销是采用字节可寻址持久性内存的长期障碍。尽管持续改进,但为了保证崩溃一致性而进行的持久化事务仍然会导致5.6倍的减速**,这使得持久化内存在实际环境中变得非常昂贵。本文介绍了一种新的方法——推测日志,它摒弃了大多数内存栅栏,通过提前记录数据值来减少数据持久化开销。该技术支持一种新的持久性事务模型——推测持久性内存事务(speculative persistent memory transaction, SpecPMT)。评估表明,SpecPMT将持久化事务的执行时间开销大幅降低到仅10%。

Memory Fence:串行化加载与存储操作

关键字 持久性内存,事务,日志,微架构

1、介绍

可字节寻址的持久性内存(如PCM)具有高密度、可字节寻址和数据持久性的特点

持久性内存在构建抗崩溃软件、改善软件性能和提高开发效率方面的潜力。

持久内存其实是一种新型的内存条、它即可以当做内存使用,也可以当做持久化外存设备使用,其不论在容量、性能、价格上都是处于两者的中间位置。

持久内存有跟硬盘一样的特性,断电以后重启,内存中的数据依然存在。

持久内存在单位价格上约为普通内存的一半,并且在单台机器上轻松达到 1.5 TB,甚至 3 TB 的内存大小。

当然引入持久内存,相比较于内存可能会带来一定的性能衰退

即使在崩溃或系统引导期间,也可以继续访问数据结构。

持久性内存事务来实现崩溃一致性:它们确保在崩溃后,持久性内存位置上的所有或没有事务更新是可观察到的。

某个操作的完成有多个步骤,其中某一步做完后系统崩溃,则会发生不一致的情况

例如:向VSFS的一个文件追加数据,那么文件系统需要进行多次写操作:

  • 需要修改文件的inode(储存文件元信息的区域)
  • 需要写文件的data块

理想:文件系统从一个一致性状态,原子地移动到另一个状态。

由于需要记录数据更新以提供事务语义,现有的持久性内存事务会产生较大的开销。(执行速度下降验证)

如图1所示,即使应用了最先进的软件(SPHT[14])或硬件(EDE[63])解决方案,与没有持久性内存事务的版本相比,STAMP[53]中的程序仍然遭受平均50-161%的执行时间开销。
在这里插入图片描述

​ 图2说明了推测日志记录的基本思想。在典型的持久事务中(图2左),在事务中更新数据之前记录数据(undo)。刷写和隔离确保在数据写入之前,日志写入得以持续。相反,**推测日志记录(图2右)将日志记录向上移动到上一次更新数据的事务。**通过这样做,可以获得几个好处。首先,日志写入利用第一个事务的提交来持久化日志,而不需要内存栅栏来持久化日志。其次,它将刷写延迟到事务提交,使事务执行得更快。第三,一旦事务提交,日志就会持久化数据的最新值,因此在同一事务中写入数据成为可选的。如果数据写入失败,崩溃后的恢复可以依靠日志记录重建更新的数据。因此,数据写入不再需要刷写。因为持久化日志记录涉及顺序写入,所以它们具有更好的空间局部性,并且比持久化数据写入(可能更随机)更快

在这里插入图片描述

​ 在效率和可恢复性方面出现了一些挑战:当事务内部或外部发生崩溃时,如何格式化和维护日志记录以支持正确的恢复?因为推测日志记录必须比事务提交的时间长,所以在存在多个事务和重复数据更新的情况下,这些记录应该保存多长时间?如何及时、非阻塞地识别和回收无用的日志记录?

​ 本文通过两种方案来解决这些问题。第一种解决方案是纯软件解决方案,与现有硬件兼容。它采用了新颖的基于紧凑日志格式和后台内存回收的推测日志管理机制,以及基于紧凑日志格式的故障恢复协议。该方案的概念验证实现比当前最先进的就地解决方案KaminoTx[51]实现了约2.7倍的加速。但是,仍然存在两个关键缺陷:(1)内存空间开销,为持久性内存空间的3倍;(2)依赖于专用的后台内存回收线程。

​ 为了在保持性能的同时减少内存空间开销,本文提出了第二种解决方案,**为混合日志模型提供了一种新的架构。该模型允许软件对热数据(即频繁更新的)使用推测日志记录,**对冷数据使用撤销日志记录。通过控制数据热度的阈值,用户可以对推测日志区域的大小设置任意的界限。该混合日志模型还支持软硬件协同设计的日志回收方案。**日志回收在前台运行,因此不需要专门的回收线程。**这允许软件用一些指令回收推测日志记录,而不会阻塞其他正在运行的线程。

具体来说,推测日志记录按时间顺序进行排序,并划分为epoch。为跟踪日志记录创建的时间,需要向私有TLB项添加一些状态位。通过简单地用新指令清除与给定epoch相关联的比特位,硬件可以轻松地回收该epoch中创建的所有日志记录。

总之,这些解决方案为当前基于撤销日志的持久事务提供了一种替代方法,即推测的持久内存事务(SpecPMT)。

SpecPMT实现了持久性内存事务的所有理想属性,同时保持较低的事务开销**:(1)它使用了就地数据更新;(2)消除了日志记录和数据更新之间的栅栏;(3)不阻塞数据持久化的事务提交;(4)支持纯软件或轻量级硬件实现;(5)它与数据结构无关,而不是特定于数据结构**

本工作的贡献有:

1、提出基于推测日志的方法,在移除栅栏的基础上,大幅减少持久性事务的崩溃一致性开销。

2、提出了一种支持软件推测日志的SpecPMT变种,它使用了一种新颖的日志组织、恢复协议和日志回收

3、提出了一种基于SpecPMT的硬件支持的推测日志机制,该机制使用了一种新的混合日志机制和基于epoch的日志回收机制,在不需要后台回收线程的情况下,限制了内存空间开销。

4、对SpecPMT的有效性进行了实证评估

2、背景

​ 持久性内存指的是使用NVM存储数据结构,以便在进程生命周期之后仍然可以访问这些数据结构,甚至在崩溃或系统启动时也可以。本文假设Intel Optane DC持久性内存硬件模型。

​ 管理软件中的持久性需要硬件支持,允许软件指定何时应该持久化数据。内存数据持久化的另一个问题是需要对持久化数据进行系统抽象。因为持久化数据必须在系统电源周期之间存在,所以应用程序必须能够找到在当前电源周期之前创建的持久数据。

​ 持久化内存事务保证事务中的写入在恢复时是原子性

3、推测日志

​ SpecPMT 是一种对undo日志的优化,通过摊销持久性内存排序指令来提高其性能。

​ 经典的undo日志记录确保了正确的恢复:(1)存在一个记录旧值的日志条目,(2)这个日志条目在位置被修改之前就持久化了。遵循这些步骤意味着,如果事务被中断或电源丢失,被失败的事务修改的任何位置都可以回滚到它们的原始值

​ 但它们并不需要这样做,而且对于持久内存,更早地迁移它们具有性能优势。

SpecPMT采用了一种基于上述观察的新策略,为每个数据保持推测日志记录。为了兼容性,SpecPMT保留了经典的持久内存事务api[59,66],如图3所示,将常规日志记录替换为推测日志记录(spog)。示例代码删除了恢复API,因为只有在崩溃后恢复时才需要它。

在这里插入图片描述

在事务中,程序员或编译器在每次持久数据更新后插入splog,为数据的虚拟地址和新值创建一个日志记录。此时不需要缓存行刷新或隔离。相反,事务通过在提交之前刷出并使用单个存储栅栏来持久化所有日志记录

崩溃会导致两种数据损坏:(1)未提交事务所更新的数据到达持久性内存;(2)已提交事务所更新的数据。SpecPMT可以同时处理这两种情况,其中它的恢复会撤销第一类,并通过丢弃未提交事务生成的所有日志记录并重放所有新的日志记录来处理第二类。如果日志记录了内存位置已提交的更新值,那么它就是新鲜的。实际上,推测日志可以作为完成事务的重做日志条目,以及失败事务的撤销日志条目。

推测日志实例

​ 在正常执行过程中,事务会产生推测日志记录并更新持久性内存中的内存位置。每个线程管理自己的日志,而不与其他线程协商。后台日志回收线程发现并回收对恢复无用的日志记录。

我们用图4中的一个运行示例来说明推测日志记录,其中显示了两个同时更新内存位置a和b的事务(该示例适用于本文提出的软件和硬件specmt .)。数据和日志的持久内存状态显示了不同时间的快照。快照在第一个事务刚刚提交时开始。这里两个位置都被更新了,并且创建了a和b的推测日志记录。当第二个事务执行时(b=10的第二个快照),它为a和b创建日志记录,并将它们添加到日志中。注意,此时,**如果发生崩溃,通过撤销对第二个事务中的a和b的任何更改,第一个事务日志记录足以将数据恢复到第二个事务之前的点。**因此,第二个事务中的新数据值和相关的日志记录可能会保留在volatile内存中。当第二个事务提交时(第三个快照),提交确保新的推测日志记录与事务提交元数据一起持久化。请注意,此时位置上的更新(例如a)不需要持久化(例如刷写),因为如果发生崩溃,第二个事务日志记录足以重播非持久化的数据更新(推测日志条目可以作为刚刚提交的事务的重做日志)。最后,在显式或隐式触发日志回收(最后一个快照)时,回收者发现第一个事务的日志记录是过期的,因此可以删除。由于没有新的日志记录,第一个事务元数据也会被删除。

在这里插入图片描述

4、软件推测日志

​ **软件推测日志的实现以日志记录的顺序组织和日志回收为核心。图5说明了高层次的实现。**在正常执行期间,事务将日志记录附加到日志区域并更新持久性和易失性内存数据。后台日志回收器使用一个易变的记录哈希索引来确定日志记录的新鲜度。恢复例程使用日志记录来撤销未提交的更新并重播最近提交的更新

在这里插入图片描述

如果事务多次更新持久内存位置,则事务只需要记录最后一次更新,因为如果创建了该数据的所有其他日志记录,则该记录将失效。陈旧的日志记录对于正常执行和恢复都是无用的,会导致额外的写流量。类似于现有的撤销和重做日志模式,事务中数据的第一次或最后一次更新可以通过写集索引或编译器辅助来发现

软件SpecPMT将日志记录组织成一个序列,新记录总是附加到序列尾部。这样的设计产生了很好的空间局部性(可以快速创建日志记录),但会浪费内存,因为多个事务对同一个数据的多次更新可能会导致多个日志记录附加到序列中。在这种情况下,数据的最新日志记录是最新的,而其他日志记录是陈旧的。为了减少内存浪费,软件specmt需要后台日志回收来移除和释放过期的日志记录。

一种更节省内存空间的方法是为每个数据只设置一条日志记录的限制。为了实现这一点,可以使用按每个数据地址索引的散列表来定位其最近的日志记录。在每次数据更新时,该设计都会用一个新的日志记录替换一个已经过时的日志记录。这样的设计节省了内存空间,但牺牲了空间局部性。考虑到持久性内存的密度比DRAM大得多,但写入速度较慢,特别是在随机写入模式下,顺序日志记录可能是更好的选择[78]。我们的实验证实了这一点,哈希表方法比顺序日志设计的速度慢3.2倍(方法见第7节)。

日志的组织

因为日志区域同时包含过期的和新的日志记录,它的组织应该鼓励快速的新鲜度检查,以帮助日志回收

软件SpecPMT将每个线程的日志区域逻辑地组织为一个记录序列,其中只能追加新的记录;因此,它保持记录的时间顺序。在崩溃恢复时,可以从最老的日志记录到最年轻的日志记录重新播放数据更新。一些未回收的过期日志记录可能仍然存在并被重新应用,但这没有问题,因为最终过期更新将被新的日志记录所取代。

由于日志序列随着持久数据写入集大小的增加而增加,并根据日志回收的频率而减小,因此很难将日志记录保留在固定大小的日志区域中。因此,**软件SpecPMT通过按需分配内存空间段(称为日志块)实现了一个动态可扩展的日志区域。**如图6所示,每个线程私有日志区域包含多个用块指针连接的日志块。每个日志块包含包含事务提交的日志记录、一组日志条目和一个前进块指针(如果是t)

在这里插入图片描述

​ 事务元数据包含日志记录的大小和日志记录的校验和。如果软件是多线程的,元数据还包含事务提交的时间戳。每个日志条目包括数据地址、大小和值。

​ 在事务启动时,软件SpecPMT为事务元数据预留内存空间。事务追加日志记录到事务执行期间的日志块。当一个日志块已满时,SpecPMT分配一个新的日志块,并使用块指针将其链接到日志序列。

​ 在提交时,事务设置日志记录的大小,并计算整个日志记录的校验和,包括元数据、日志条目和块指针。校验和还用作事务的提交状态:如果校验和与日志记录匹配,则软件认为事务已提交;检查和被刷新并隔离,以确保事务完成时的持久性。

背景日志回收

​ 日志回收在专用线程的后台进行。回收通过API显式触发,或者在事务执行发现内存空间开销达到可调阈值时隐式触发。日志回收能够根据软件的持久数据写入集大小,降低日志记录的内存消耗。理想情况下,每个更新的持久数据只与一条日志记录相关联。

​ 在一个日志回收周期中,回收器从一个日志块开始向后扫描,沿着日志块链遍历到最古老的日志块。虽然当扫描从最年轻的日志块(即尾部)开始时,这是最有效的

​ 性能和崩溃一致性是日志回收的重要方面。为了保持高性能,日志回收在扫描日志记录时使用哈希表来确定给定日志记录的新鲜性。因为散列表将地址映射到条目,任何由此产生的冲突都会很快暴露出潜在的过期日志记录。散列表本身并不要求崩溃时的一致性,因为它可以在受到崩溃影响时重新构建,而且如果崩溃中断了散列表,可以从头开始重复回收日志。根据上述观察,我们选择在易失性内存中分配散列表,这在允许崩溃时重建策略的同时提高了性能。

​ 当回收器执行周期性压实时,性能也得到优化。对于每个时间压缩周期,回收器分配新的日志块,并将旧日志记录中的新日志条目复制到新块中,形成新的紧凑日志记录,其中时间戳设置为最新的日志条目。完成后,回收器将新的日志块插入链条中。前一个步骤(复制)可以在崩溃后重复。因此,只有后一个步骤(插入新的日志块)必须以持久的原子方式执行。在不依赖事务的情况下实现这一目标

程序设计模型

​ 切换崩溃一致性机制。软件组件可以建立在其他崩溃一致性机制上,如撤销(即PMDK)或重做日志事务,这允许这些机制与推测性日志共存,并增加实用性和兼容性。为了实现这一点,SpecPMT允许从推测性日志记录切换到另一种崩溃一致性机制。因为SpecPMT使用就地更新,它只需要在转换点刷新持久数据的脏缓存行。一旦完成,崩溃恢复就不再需要推测日志,新模型从此以后就可以使用了。软件应该确保在转换点上没有运行SpecPMT。刷新可以通过整个缓存刷新来执行,例如,使用指令,如wbnoinvd,或通过软件分析进行选择性刷新

​ 当软件更新由其他软件或同一软件的其他执行生成的持久数据时,可能没有与数据相关的推测日志记录。这导致了SpecPMT的一致性问题。为了解决这个问题,软件可以在修改数据之前创建快照,以一种与崩溃一致的方式更新外部数据。

​ 并发控制。SpecPMT提供了原子持久性,并依赖于软件在多线程上下文中提供隔离。该软件可以将SpecPMT与并发控制机制相结合,

5、硬件支持

​ 虽然推测日志的纯软件设计实现了高性能的崩溃原子性,但它有多个缺点**:它的内存空间开销几乎是原来的三倍,而且它需要一个专门用于及时回收后台日志的内核。后台日志回收线程还需要调整回收的触发级别并增加内存带宽压力。**为解决这些挑战,本文提出对选择性日志的硬件支持,我们将其称为硬件 SpecPMT。

​ 硬件 SpecPMT进行体系结构更改以支持(a)识别热页,(b)执行撤销日志记录,©执行批量复制的原语。这些原语支持两种新颖的角色:撤销推测混合日志记录和基于epoch的日志回收。

混合日志

​ 硬件SpecPMT的混合日志将快速但消耗内存的推测日志与缓慢但节省内存的撤销日志undo相结合,前者用于频繁更新的数据(即热数据)——这只占软件内存占用的一小部分——后者用于不经常更新的数据(即冷数据)。

​ 硬件SpecPMT依赖硬件支持,根据页面上的数据更新频率在页面粒度上区分热数据和冷数据。在事务中,页面可以在热和冷之间切换。图7说明了如何根据数据热转换来处理日志开关。

在这里插入图片描述

​ 该图说明了四个连续的事务更新相同的数据,并在冷事务和热事务之间交替。在第一个事务中,数据最初被标识为cold;因此应用了undo logging。在第二个事务中,由于额外的数据更新,数据变为热点,页面从撤销日志切换到推测日志。在第三个事务中,数据被推测地记录(以缓存行粒度),因为它仍然是热的。在最终的事务中,数据从热数据切换到冷数据,并且由于它已经在前一个事务中进行了推测性的日志记录,因此不需要额外的日志记录。对于可以作为撤销日志的数据,必须有一个先验的推测日志记录。但是,为简单起见,硬件specmt对冷页采用了相同的日志记录策略。

为了区分热页和冷页,我们可以将元数据与页表项关联起来,以记录每个页的热度。但这需要修改操作系统的页表和页异常处理程序部分。为了避免对操作系统的修改,我们**将额外的元数据与每个快表(TLB)条目关联起来**,如图8所示。**这使得可以只跟踪TLB覆盖的页。**如果TLB项被清除或失效,则无法再跟踪该页,但这样的页很可能不再是热点页。通过TLB项跟踪热页的主要好处是较低且有界的内存开销**,因为推测日志记录的内存消耗取决于所应用的页的数量,而TLB只覆盖固定的一小部分页,因此混合日志记录的内存开销要小得多且有界。**

现代 CPU 都包含一张名为 TLB(Transfer Look-aside Table),叫做快表,或者高速地址变址缓存,以加速对于页表的访问。加入 TLB 之后的完整地址映射长这样:

在这里插入图片描述

​ 在混合日志记录下,TLB在写入数据时进行检查。在TLB命中时,控制器可以确定该页是热页还是冷页。在TLB未命中时,控制器将这样的页视为冷页。如果该页是热页,则推测性地记录日志,并将数据写入操作直接更新L1缓存。否则,硬件在更新缓存行之前为其创建undo日志记录。

​ 用于热度跟踪的额外元数据的详细信息如图9所示。每个TLB项包含一个1位的EpochBit和一个3位的饱和计数器。如果设置了EpochBit,表示该页已经被推测记录,则“cnt/EID”记录了基于epoch的日志回收(将在5.2节讨论)的epoch ID。如果EpochBit是明确的(表示该页是冷的),则计数器记录该页在TLB中驻留期间的事务性存储操作的数量。在计数器到达阈值(为简单起见,即最大值)时,认为该页已经变热。这样的页面将开始投机性地记录日志(即,将整个页面复制到日志中)。这种转换是使用硬件批量复制引擎39完成的。在推测日志记录期间,硬件不会阻止对页面的访问,因为它仍然在存储操作之前为数据创建undo日志记录。日志记录完成后,硬件设置EpochBit,并根据epoch ID寄存器将计数器设置为当前epoch ID。

在这里插入图片描述

​ 如前所述,如果硬件清除一个TLB项,相关的epoch ID和计数器将被丢弃,我们将该页视为冷页。由于每个核都维护自己的局部历元ID和热度计数器,硬件SpecPMT避免了不同核上tlb之间昂贵的同步

​ 除了对TLB的修改,硬件SpecPMT还为每个L1缓存项扩展了两个单比特标志。这些标志指定缓存控制器如何处理事务提交或缓存行回收。PBit表示在事务内部或外部回收时,缓存行是否需要持久化。控制器在更新热页的缓存行时设置该比特位。

​ 缓存控制器在撤销记录缓存行日志后,或在事务提交或缓存回收时需要推测记录缓存行日志时,设置LogBit。例如,如果两个比特位都设置了,硬件就需要持久化并在事务提交或回收时推测地记录缓存行。如果只设置了LogBit,则在事务中取消记录缓存行。硬件在事务提交时清除LogBit,但保留PBit。

在cache一致性事件中使推测记录的缓存行无效是不变的,这是一个引人注目的特性,因为修改一致性协议容易出错,可能会影响性能。一旦进行了推测日志记录,失效的缓存行就不需要持久化了。考虑MSI一致性,其中事务写入𝑤1将缓存行转换为M状态并提交。另一个核心上的后续事务将相同的数据更新到𝑤2。硬件将脏缓存行写回共享缓存,然后将状态从M转换到i。在事务中,硬件分别为𝑤1和𝑤2创建一个推测日志记录。如果包含𝑤2的事务在系统崩溃之前提交,则恢复将使用更新的日志记录来恢复缓存行的最新值,即𝑤2。如果崩溃中断事务,则恢复使用𝑤1的日志记录来撤销𝑤2的效果。在这两种情况下,系统不必保持𝑤1的效果。每个核心维护自己的推测日志记录,并记录每次事务提交的时间戳。恢复首先使用时间戳来查找数据最近提交的推测日志记录。

正确性

​ 混合日志保证了软件的可恢复性,因为它确保每个未提交的事务更新都与一个日志记录相关联,无论是撤销的还是推测的。考虑一个因崩溃而中断的事务中的冷页面更新。无论页在事务中是否变为热点,硬件都会在执行更新之前取消缓存行。关于热页面更新,有两种情况。如果页面在事务开始之前是热的,则必须有一个关于更新数据的推测日志记录。否则,如果该页在事务中变为热状态,则硬件必须在将该页设置为热状态之前预先记录该页。页面日志记录用作事务中后续更新的撤销日志记录。

​ 协议维护了两个不变量:(1)所有未提交的undo日志记录都是新鲜的;(2)所有未提交的页面日志记录作为某些数据的撤销日志和其他数据的推测日志,必须在同一事务中创建页面日志记录之前进行撤销日志记录。

​ 因此,恢复机制通过3个步骤来撤销所有未提交的事务更新并保留所有已提交的更新:(i)将未提交的推测页日志记录应用到数据上;(ii)将未提交的undo日志记录应用于数据;(iii)按时间顺序应用提交的推测日志记录。

性能保证

虽然硬件以缓存行粒度对热页执行推测日志,但当页面从冷切换到热时,硬件以页级别粒度执行推测日志。因此,如果页面上只有少量更新,那么推测日志记录可能会增加执行的延迟,以及向持久性内存写入数据的流量。有几个方面可以降低这种可能性。首先,硬件SpecPMT只记录热页,而热页往往在一个周期内被写入多次。其次,推测日志将刷新推迟到事务提交,允许事务内日志的写合并。它还将数据持久性推迟到缓存行回收,允许跨事务的数据写合并。第7节量化了硬件SpecPMT对写流量和内存消耗的影响。第三,硬件可以提供一个API来启用/禁用推测日志,它会设置/重置控制状态寄存器位。这允许程序员或用户在产生不利性能影响时禁用推测日志记录(并仅依赖撤销日志记录)。最后,硬件SpecPMT可以对一个频繁执行的事务进行撤销日志记录和推测日志记录的性能抽样,以比较和选择性能更好的日志记录方案。

基于Epoch的日志回收

​ 硬件SpecPMT相对于纯软件解决方案的另一个优势是,它执行回收的方法是基于Epoch的、快速的、在前台的、线程本地的。线程局部回收一直是重做日志优化的长期目标[13 - 15,25,26,46]。事务执行模型必须将最新的重做日志记录应用到数据中,这通常需要同步或大量的硬件修改。与重做日志不同,推测日志在不需要线程同步的情况下在本地查找过时的日志记录。

​ 硬件SpecPMT基于Epoch的日志回收是一种软件硬件协同设计,它提供了两个关键的好处:(a)它允许软件通过按时间回收混合日志记录来设置任意的内存消耗限制,(b)它允许每个线程回收它的线程本地推测日志记录,而无需咨询其他线程

硬件SpecPMT中的日志回收是通过将线程执行划分为多个epoch来实现的。每个私有TLB条目都使用一个epoch ID进行扩展,以记录页面被推测记录的时期。在日志回收周期中,软件通过在TLB中清除epoch ID来回收在epoch内创建的所有推测日志记录。基于时代的日志回收的核心思想是用一条指令将一组具有相同时代ID的热页切换为冷页。硬件清除每个TLB条目的epoch位和EID字段,以将页面设置为冷的。增加了两条新的指令,clearepoch EID和startepoch EID,分别以给定的纪元ID结束和开始纪元。只要软件总是清除最古老的纪元,它就会在日志区域的开始处回收日志记录,因为日志记录是按照时间顺序连接的。

当事务提交时,硬件扫描L1缓存以找到事务更新的脏缓存行。它为推测日志的页面和缓存行创建并持久化日志记录。它跳过了那些更新的缓存行的持久性。它持久化undo日志缓存行。

硬件SpecPMT允许在事务中更新的L1缓存线溢出到L2缓存,只要硬件在退出之前预先记录了缓存线。这使得大型交易能够成功。

回收包含了一组数据结构和硬件组件,如图10所示,包括日志记录、DRAM中的8个epoch指针、维护指针和寄存器的硬件,以及启动和回收一个epoch的两条新指令。日志记录在逻辑上按时间分组,但在物理上存储在日志块中。epoch指针指向每个epoch日志记录组的日志记录的头部。

在这里插入图片描述

顺序软件的日志回收

​ 在正常执行过程中,硬件SpecPMT软件会在每个事务提交后检查是否回收日志记录。这些检查可以是可选的和自适应的,因为日志回收只是偶尔需要。软件负责确定回收哪个时期。这项工作采用了一种直截了当的策略,总是重新找回最古老的时代。

软件分三个步骤进行日志回收。与处理事务模式切换(第4.3节)类似,它首先将所有推测记录的数据保存在当前epoch。这可以通过扫描日志记录并通过clwb选择性地刷新日志记录中指定的数据地址来实现,或者通过wbnoinvd等指令回写整个L1缓存。

在第一步完成后,在第二步中,软件调用一个新的非特权指令clearepoch EID,通过清除与EID匹配的页面的EpochBit和cnt/EID字段来将一些页面从热切换到冷。这些页面最初被推测地记录在编号为EID的时代。第三步,回收纪元日志记录占用的内存空间。该软件在没有排序约束的情况下执行第二和第三步

通过使用L1缓存扫描和数据持久化语义扩展clearepoch,可以合并第一步和第二步。这种设计还可以进行优化,避免在一个页记录在旧纪元时,但它的一些缓存行也记录在新纪元时进行过度的数据持久化。硬件在回收旧纪元时可以跳过持久化这些缓存行。这种优化为L1缓存中的每一行增加了3个额外的比特位。

​ 该软件以一个新的非特权指令startpoch EID开始一个新的纪元,其中EID指的是新纪元的ID。该指令将epoch ID寄存器赋值给EID。Epoch ID 0用于冷页。

​ Epoch大小的选择涉及一个权衡。小epoch会导致过多的日志回收、TLB和缓存刷新,而大epoch会消耗更多的内存空间。在当前的实现中,当epoch包含超过2MB的记录或200个推测日志页面时,我们就开始了一个新的epoch。第一个阈值限制内存消耗,而第二个阈值将推测记录的页面分配到不同的epoch以提高性能。

多线程软件的日志回收

​ 多线程软件在正确性和可扩展性方面带来了挑战。图11演示了一个示例,该示例涉及两个线程执行对相同数据的写操作,事务显示在黑盒中。从图中可以看出,回收一个线程周期可能会在崩溃时导致数据损坏。具体来说,当第二个线程回收其epoch时,它将删除𝑤2的推测日志记录。稍后,当另一个线程更新数据(𝑤3),但在事务提交之前遭遇系统崩溃时。在这种情况下,由于无法恢复到𝑤2之后的状态,恢复操作无法撤销更新

在这里插入图片描述

​ 为了解决这个问题,我们提出了一个简单的非阻塞回收协议。如果一个epoch的epoch ID被重新分配给了同一线程的一个更年轻的epoch,我们就让它处于非活动状态。形式上,该软件可以安全地回收纪元𝑒中的所有日志记录,如果:(1)𝑒是一个不活跃的纪元;(2)所有活动的epoch必须在𝑒结束后开始,包括属于其他线程的epoch。

​ 该协议保留了可恢复性。考虑一个纪元𝑒内的推测日志数据𝑎。因为𝑒是不活动的,所以在软件将纪元ID重新分配给一个更年轻的纪元之前,软件必须清除所有推测记录在𝑒中的页面的纪元位,包括包含𝑎的页面。如果软件在一个封闭的活动纪元中更新𝑎,这意味着纪元已经结束,但它的纪元ID没有被重新分配,那么在𝑒中创建的𝑎日志记录是陈旧的,可以安全地回收。如果软件以一个开放纪元更新𝑎,因为软件从𝑒结束之前的每个纪元开始循环,那么软件必须将𝑎页视为一个冷页。然后软件必须在更新之前撤销日志𝑎。

硬件SpecPMT通过让每个线程维护一个未回收纪元最早开始的时间戳来实现该协议。在回收纪元时,软件会检查所有线程的时间戳和相关纪元的活跃程度。如果活动纪元与要回收的纪元重叠,则软件将检查和日志回收推迟到进一步的事务开始或提交。

​ 硬件光谱恢复方法与软件光谱恢复方法相同。它扫描每个线程的日志记录,并根据时间戳重放它们。

其他问题

持久缓存

​ 有些处理器可能提供持久或电池支持的缓存层次结构,如eADR[59]。如果处理器在缓存中保留事务的整个写集,并提供一种机制来识别和丢弃保留在缓存中的未提交数据更新,那么它可以在不记录任何数据的情况下运行事务。然而,由于昂贵的硬件和维护代价,eADR的采用可能会限制[59]。随着缓存和系统(例如NUMA)的增大,开销会进一步增加。

事务失败

​ 持久性内存事务可能在应用程序或系统异常时中止,例如耗尽内存空间。尽管软件总是可以通过缓慢的崩溃恢复例程来撤销中断事务的影响,但它可以利用事务内存的事务中止机制来启用正常执行期间的快速中止,例如将写入集保留在私有缓存中,并在中止时丢弃所有未提交的更新。

硬件成本

​ 硬件SpecPMT需要0.91KB的片上存储。它为每个L1-和L2-TLB条目添加两个比特;以及每个L1数据缓存项的两个比特。对于Skylake微架构,L1数据缓存、L1-和L2-TLB分别包含512、64和1536个条目。硬件还专门使用两个寄存器来保留事务状态和当前epoch ID。总的来说,硬件SpecPMT为Skylake核心带来不到0.04%的片上存储。

6、讨论

选择使用

​ 推测日志可以增强持久的预写日志事务,不管它们使用什么存储,比如SSD或远程内存。与支持数据库系统[64]、文件系统[38,85]和分布式存储系统[7,86]的预写日志的典型实现不同,猜测日志不需要软件缓存(例如由数据库管理的缓冲池)来保留数据更改,但仍然允许由事务产生的日志记录和数据更改以任何顺序到达持久域。因此,对于预写日志在一致性、崩溃恢复和性能方面发挥关键作用的系统,推测日志可以潜在地减少事务提交延迟、提高吞吐量并减少写入流量。

备选设计

​ 推测日志事务没有绑定到特定的实现,如本文提出的设计。例如,一种设计可以将热度检测任务转移到软件上。软件可以使用一个性能监控单元[84]或操作页表项[21,77,80]来采样或统计对页的访问次数,而无需修改硬件。硬件只执行历元控制。

编译器优化

​ SpecPMT可以使用编译器来减少维护日志记录时的内存消耗。鉴于编译器有时可以推断事务将更新哪些数据以及何时更新,软件可以丢弃日志记录,然后在适当的位置重新构建它们。

7、评估

本节评估所提议的解决方案的性能。它提供了性能增益的根本原因分析,包括写流量和围栏数量的减少

基准

​ 使用除bayes之外的所有事务应用程序评估了软件和硬件推测日志。使用libvmmalloc[3,81]将事务性应用程序移植到持久内存,它将动态内存分配覆盖到持久内存分配。我们使用STAMP非模拟器输入对软件方案进行评估,使用模拟器负载对硬件方案进行评估。kmeans和vacation应用程序有两种工作负载:低争用和高争用。我们两个都用。其他应用程序只有一个工作负载。

软件平台

​ 在配备1TB@2,666MT/s(8个内存)第一代Intel Optane持久性内存和128GB@2,666MT/s DDR4内存的Intel Gold 6230机器上评估了软件解决方案。我们使用启用dax的文件系统挂载持久性内存

  • 硬件仿真

​ 为了方便起见,我们在x86核心模型上构建了模拟器,但该设计并不局限于特定的指令集架构。我们的模拟器构建在系统级Gem5模拟器[12]之上。我们用Gem5集成内存子系统模拟器Ruby评估修改后的缓存。表1列出了模拟硬件的参数。

我们将硬件SpecPMT (SpecHPMT)与两个持久内存事务和两个次优设计进行比较。

软件解决方案评估

​ 如图12所示。与PMDK和Kamino-Tx相比,SpecSPMT-DP算法的平均性能分别提高了3倍和1.78倍。SpecSPMT通过移除数据持久化来提高性能。与PMDK和Kamino-Tx相比,加速比分别为5.1倍和3.02倍

在这里插入图片描述

​ 当应用程序更新大量数据时,SpecSPMT-DP的性能明显优于Kamino-Tx,因为SpecSPMT-DP在每次更新后都会删除所有栅栏。例如,在事务更新次数最多的5个应用程序上,SpecSPMT-DP比Kamino-Tx至少快1.5倍,如表2所示。我们将这五个应用程序归类为写密集型应用程序。在4个适合写处理的应用中,SpecSPMT-DP比Kamino-Tx的运行速度快不到1.4倍。

在这里插入图片描述

​ SPHT[14]卸载数据持久化到后台replayer线程。在事务提交的关键路径上,只保存重做日志记录。通过消除日志操作上的栅栏,SPHT的性能优于Kamino-Tx,与SpecSPMTDP具有相似的加速效果。

​ 由于SpecSPMT可以移除强制数据持久化,因此在写密集型应用上,它的性能比SpecSPMT- dp高出9.9倍。然而,在写适中的应用程序上,SpecSPMT仅比SpecSPMT- dp快5%。在事务规模较大的写密集型应用程序中,它可以显著提高速度。具体地,在平均事务大小大于20字节的kmeans和yada两个版本上,SpecSPMT分别获得了9.9倍、5.4倍和1.6倍的加速另外两个写密集型应用程序,入侵者和ssca2,具有平均4字节写集的小事务。通过移除数据持久性,SpecSPMT带来了10%的速度提升。

硬件方案评估

​ SpecHPMT比基线EDE平均高出1.41倍,如图13所示。除了kmeans-low之外,spechmt在诸如软件解决方案这样的写密集型应用程序上实现了显著的加速。该应用程序将大量时间用于连续事务之间的计算,从而使硬件有足够的时间在下一个事务开始之前清空写待决队列。kmeans-high算法的计算量较小,因此在持久数据更新成为性能瓶颈的情况下具有更高的加速比。
在这里插入图片描述

​ 平均而言,HOOP比EDE快1.19倍,因为它将数据持久性移出事务提交的关键路径。通过合并来自多个事务的日志记录,它还减少了18.9%的内存流量。

​ 虽然HOOP减少了关键路径的延迟,但它偶尔的垃圾收集耗尽了内存控制器上的写缓冲区,导致与应用程序工作线程的密集写竞争。spechmt通过允许投机性记录的数据留在缓存中或在缓存回收时自然溢出到持久内存来避免这种争用。因此,尽管HOOP需要额外的核心和超过200倍的片上存储空间,但它的平均性能比HOOP高1.21倍。

​ SpecHPMT仅比理想情况差0.09倍(即1.5倍的加速比与SpecHPMT的1.41倍),即no-log。在labyrinth和yada上,spechmt的性能甚至超过了no-log,因为它用顺序日志写取代了分布式持久内存写,而顺序日志写在持久内存[11]上更快。

​ SpecHPMT-DP算法消除了日志和更新操作之间的顺序关系,在性能上与EDE算法几乎相同,从而带来了边际的加速比。它们在数据和日志持久性上造成的写入流量大致相同,如图14所示。唯一的区别是EDE维护日志和数据更新操作之间的顺序,而SpecHPMT-DP不维护。然而,乱序核心隐藏了排序的开销。

​ spechmt的写流量在所有设计中倒数第二。在所有设计中,EDE和SpecHPMT-DP产生的写流量最多。与EDE和SpecHPMT-DP通过单独的事务合并数据持久性不同,HOOP也持久化日志和数据,而HOOP是跨事务合并数据持久性。如果多个事务多次记录相同的数据,GC将合并日志记录并仅应用最新的记录数据。因此,HOOP在一半的应用程序上实现了与spechmt一样低的写流量。此外,HOOP为事务中的每次数据更新和缓存未命中创建日志记录。因此,它会在内存占用比剩余应用平均多两倍的应用程序(ssca2、vacation、yada)上产生过多的日志。相比之下,spechmt仅为数据更新创建日志记录。

内存消耗

​ 如果软件将更多的内存空间分配给日志区域,则spechmt可以获得更高的加速,这意味着硬件会推测日志更多的数据。与HOOP不同,片上映射表的大小限制了日志的大小;spechmt的日志面积可以无限增长。我们改变epoch的大小来分析对内存消耗的敏感性。图15显示了平均内存消耗的平均加速和写入流量的减少。当基准测试可以承受15%和20%的额外内存消耗时,它们分别获得了1.36倍和1.4倍的加速。即使内存消耗很小(2.6%),加速仍然很大(1.12倍)。

在这里插入图片描述

​ 小epoch会影响性能,因为软件会记录页面,并在更新页面上的任何数据之前回收日志记录。当内存消耗在2.6% ~ 14.6%之间时,Vacation会观察到26% ~ 8%的性能下降。5.1节描述了一种将系统还原为撤销日志记录的优化,以避免这种不必要的性能损失。

8、相关工作

9、总结

​ 提出了一种新的日志记录方法——推测日志,它可以移除大多数事务中的栅栏和数据持久化,强制立即持久化,并执行直接内存加载和就地数据更新。我们讨论了一种仅支持软件和硬件的推测日志设计。前者实现了10%的执行时间开销,而最先进的解决方案为232%。后者在限制内存消耗的同时保持了纯软件解决方案的性能。与最先进的undo和redo日志相比,它的执行时间开销分别降低了86%和76%,同时只需要0.91KB的片上存储开销。

在更新页面上的任何数据之前回收日志记录。当内存消耗在2.6% ~ 14.6%之间时,Vacation会观察到26% ~ 8%的性能下降。5.1节描述了一种将系统还原为撤销日志记录的优化,以避免这种不必要的性能损失。

8、相关工作

9、总结

​ 提出了一种新的日志记录方法——推测日志,它可以移除大多数事务中的栅栏和数据持久化,强制立即持久化,并执行直接内存加载和就地数据更新。我们讨论了一种仅支持软件和硬件的推测日志设计。前者实现了10%的执行时间开销,而最先进的解决方案为232%。后者在限制内存消耗的同时保持了纯软件解决方案的性能。与最先进的undo和redo日志相比,它的执行时间开销分别降低了86%和76%,同时只需要0.91KB的片上存储开销。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值