Intel PMEM的使用经验和指南

Optane Memory结构

结构总览

英特尔的Cascade Lake处理器是第一个(也是目前唯一一个)支持Optane DIMM的CPU。Optane DIMM与普通的DRAM一样位于内存总线上,并连接到处理器的iMC (integrated memory controller),如图1(a)所示。图中所示的CPU包含两个iMC,每个iMC包含3个channel。

iMC位于ADR(asynchronous DRAM refresh )域中,其保证了数据从cache flush完成后,便可保证数据的持久性。或说ADR特性保证了在发生了掉电故障时,iMC可以将数据刷入3D-XPoint介质(保证100us内,将数据写入NVDIMM)。如图1(b)所示,每个Optane DIMM的ADR区域都包含RPQWPQ( read and write pending queues ),当数据到达WPQ,便保证了数据不丢。因为,处理器的cache不属于ADR域,所以只有当属于cache的数据写入WPQ,才能保证持久性。

iMC与Optane DIMM 通过DDR-T接口以cache line粒度(64B)通信。DDR-T的接口允许异步命令和数据定时(asynchronous command and data timing)。

Intel PMEM的使用经验和指南

如图1(b)所示, 对NVDIMM的访问首先到达DIMM上的控制器(本文中称为XPController),该控制器协调对Optane介质的访问。与SSD相似,Optane DIMM执行内部地址转换以实现损耗均衡和坏块管理,并为该转换维护AIT (address indirection table)。
地址转换后,将实际访问存储介质。由于3D-XPoint物理介质的访问粒度为256B(文中称为XPLine),所以,XPController会将较小的请求转换为较大的256字节的访问以提升性能。然而,因为同样的原因,小数据量的存储会变为RMW(read-modify-write)操作而导致写放大。 XPController有一个小的写合并缓冲区(在本文中称为XPBuffer),用于合并地址相邻的写操作。 由于XPBuffer属于ADR域,因此到达XPBuffer的所有更新都是持久的。

Operation Modes

Optane DIMM支持两种模式,Memory 模式APP Direct模式。在Memory模式中,DRAM作为Optane DIMM的cache,而Optane DIMM作为易失的主存。在APP Direct模式中,Optane DIMM作为一个分开的PM,直接供其他应用如文件系统使用。
如图1(c)所示,Optane memory可以被配置为交错模式(interleaved across channels and DIMMs)。在现有的平台中,支持的交错大小为4 kB,这可以确保对单个page的访问将只访问单个DIMM,而如果有六个DIMM,则大于24 kB的访问将访问所有DIMM。

ISA (Instruction Set Architecture) Support

在App Direct模式下,应用程序和文件系统可以使用CPU指令访问Optane DIMM。 ISA为程序员提供了许多选择来控制数据写入的顺序。
应用程序使用store命令来将数据写入Optane DIMM,写入的数据最终被持久化。 但是,store命令的顺序可能被重排,而无法进行正确的故障恢复。 当前的Intel ISA提供了clflushclflushopt指令可将cache line刷回内存,而clwb可以对高速缓存行进行write back(不会evict)。也可以使用非临时性存储(例如ntstore)绕过高速缓存,直接写入内存。 所有这些指令都是非阻塞的,使用sfence命令可确保之前的高速缓存的刷新,写回或非临时存储操作是完整且持久的。

实验系统和配置

系统描述

测试系统有两个CPU槽(socket)。每个CPU为英特尔的Cascade Lake处理器。每个CPU有两个iMC,每个iMC有3个内存通道(一个CPU共6个通道)。每个iMC内存通道绑定32GB DRR4 DIMM (2 socket × 6 channel × 32 GB/DIMM) 或 256GB Intel Optane DIMM (2 socket × 6 channel × 256 GB/DIMM) 。系统配置了384GB的DRAM和3TB的NVM。

实验配置

本文主要测试,Optane DIMM作为一个持久性设备(即APP Direct模式)的性能,同时总结其使用指南。
Linux通过在物理内存的连续范围内创建pmem namespace 来管理持久内存。后背实际的介质,可以由交错(interleaved)或不交错(non-interleaved)Optane memory支持,也可以通过DRAM仿真支持。 本文将测试这三种介质的性能差异。

介质性能特征

本章通过实验数据从多维度的描述Optane DIMM的性能特征,其并不是简单的比DRAM慢一些而已。这些特征的描述能够使用户更加高效的使用该介质。

典型延迟(最好情况)

测试方法

读延迟, 从顺序和随机存储器地址中读取8B的数据的平均延迟。 为了消除cache和queue的影响,我们清空了CPU流水线,并在两次读操作之间使用memory fence(mfence)操作
写延迟先将cache line 加载到cache中,然后测量下面两个指令序列中的任意一个的延迟:

  64-bit store +clwb + mfence; 
  ntstore + mfence。

测试结果及说明

测量的结构反映的是软件看到的介质延迟,而不是底层介质本身的延迟。
对于读,包含以下部件产生的延迟:on-chip interconnect,iMC, XPController, 和实际的3D-Xpoint 介质。
实验结果(图2)显示,Optane的读延迟比DRAM高2到3倍。 大部分差异是由于Optane的介质延迟更大导致的。 Optane也比DRAM更依赖于访问模式。 DRAM的随机访问和顺序访问相比,性能差异为20%,而因为XPBuffer存在的原因,Optane的性能差异达80%。
对于写,一旦数据到达iMC的ADR域,内存的store和fence指令就成功完成,因此DRAM和Optane的延迟相近。 非临时存储的开销比使用高速缓存刷新(clwb)的开销更大。

Intel PMEM的使用经验和指南

一般来说,同一种测试下,Optane的延迟差异非常小,表现为测试数据的方差很小。 例外的是,Optane DIMM的顺序读操作的延迟方差更大,这是因为第一个高速缓存行(64B)访问将整个XPLine加载到XPBuffer中,随后的三个访问(因为测试读时会清空高速缓存,这里从存储介质的视角出发,故 256/64 - 1 = 3)可直接读取缓冲区中的数据。

Tail Latency

测试中,load和store的延迟非常的稳定。然而,当访问集中在热点(hot spot)时,延迟异常的store操作数会增加。图3描述了尾部延迟和访问局部性之间的关系。 该图描述了 99.9th、99.99th以及最大延迟与热点大小的关系。

测试方法

单个线程对一个热点(为某个大小的循环缓冲区)进行2000万个64字节的写操作。

Intel PMEM的使用经验和指南

测试结果及说明

异常点的数量(尤其是超过50μs的异常值)随着热点大小的增加而减少,而DRAM不存在此种现象。这些峰值虽然出现频率很低(占访问的0.006%),但是其延迟比普通的Optane访问高2个数量级。 怀疑这是由于磨损均衡(wear-leveling)或温度过高(thermal concerns)造成的,但不确定。

带宽

带宽一般影响整个系统的吞吐。本文测试了不同并发下的随机/顺序的读/写带宽。

测试方法

图4展示了不同线程数目以256B的粒度访问相应介质的顺序读写的带宽。对于写操作使用了ntstoreclwb两种方式。图从左到右记录的依次是interleaved DRAM、non-interleaved Optane、interleaved Optane的带宽。对于non-interleaved Optane,所有的访问只访问单个DIMM。
图5展示的是访问的粒度变化的情况下的随机读写的带宽。对于不同的测试,使用不同的线程数(图中表示为 “读线程数/ntstore线程数/store+clwb线程数”)以使得介质获得最佳性能。

实验结果说明

DRAM带宽不仅比Optane高,而且性能可以根据线程数进行可预测的扩展,直至DRAM带宽饱和(图4左),并且与访问大小无关(图5左)。

Intel PMEM的使用经验和指南

Intel PMEM的使用经验和指南

Optane的结果截然不同。 首先,对于单个DIMM,最大读带宽是最大写带宽的2.9倍(图5中,6.6 GB/s 和 2.3 GB/s),对于DRAM,读写性能差距较小(只有1.3倍)。其次,除了交错DIMM的读操作之外,Optane的其他操作的性能与线程数的关系都是非单调的(图4,具体原因见):对于非交错(即单个DIMM,图4中)的情况,性能会在一到四个线程之间达到峰值,然后逐渐下降;对于交错的情况,store + clwb操作的峰值可以保持到十二个线程,然后开始下降。 第三,Optane 256 B以下的随机读写的带宽很低, 该拐点对应于XPLine的大小。

交错(将访问分布在所有六个DIMM上)进一步增加了复杂性:图4(右)和图5(右)测试了六个交错的NVDIMM的带宽。 交错将读写带宽的峰值分别提高了5.8倍和5.6倍。 提升的倍数与DIMM的数量匹配。 该图的最显着特征是当访问的粒度是4 kB时,有性能下降。这种下降是由iMC中的竞争引起的,当每个线程随机访问的大小接近交错大小时,下降将会达到最大值(具体原因见)。

Optane DIMM的最佳实践

为了构建基于Optane DIMM的系统并对其调优,基于实验数据,本文将介质的规律提炼为以下四个原则:
1.避免小于256 B的随机读写;
2.尽可能使用ntstore(non-temporal stores)进行大数据量的写,以及控制CPU高速缓存的换出;
3.限制访问Optane DIMM的并发线程数;
4.避免NUMA访问(尤其对于是read-modify-write操作序列)。
下面详细解释这四个原则。

避免小数据量(小于256B)的随机读写

对于随机读写,图5已说明了介质带宽与访问对象的大小关系。本节继续探索小数据的随机写。

Optane的数据更新,在内部介质会进行read-modify-write操作。若更新的数据量小于内部操作的数据粒度(256B),会带来写放大,而使得更新效率低。
为了更好的描述下面的实验现象,引入了EWR(Effective Write Ratio,由DIMM的硬件测量)的概念:其为iMC发出的字节数除以实际写入3D-XPoint介质的字节数,即为写放大的倒数。EWR小于1表示,Optane介质写效率低。EWR也可以大于1,此时表示XP-Buffer做了写合并(在内存模式中,因为DRAM的缓存作用,EWR也可以大于1)。

Intel PMEM的使用经验和指南

图8展示了Optane DIMM的带宽(三种store命令)与EWR的正相关的关系。一般而言,小数据量的存储使得EWR小于1。 例如,当使用单个线程执行随机的ntstore时,对于64字节的写,EWR为0.25,对于256字节访问,其EWR为0.98。
值得注意的是,虽然iMC仅以64B为单位访问DIMM,但是XPBuffer可以将多个64B的写进行缓存,并合并为256B的Optane内部写,所以256字节更新是高效的。由上可知,如果Optane DIMM的访问具有足够好的局部性,同样可以高效地进行小数据量的存储。 为了得到“怎样的局部性才足够”的命题结论,我们设计了一个实验来测量XPBuffer的大小。 首先,我们分配N个XPLine大小(256B)的连续区域。 在实验中,进行循环的写数据。首先,依次更新每个XPLine的前半部分(128 B), 然后再更新每个XPLine的后半部分。 我们测量每一轮后EWR的值。 图9显示: N 小于64(即16 kB的区域大小)时,EWR接近于1,其表明,后半部分的访问命中了XPBuffer。 N 大于64时,写放大进行了突变,其由XPBuffer miss急剧上升导致。这表明,XPBuffer的大小为16KB。进一步的实验表明,读操作也会占用XPBuffer中的空间从而造成竞争关系。
总结:避免小数据量随机写,如果不可能避免,则将操作的数据集大小限制为每个Optane DIMM 16 KB。

Intel PMEM的使用经验和指南

使用ntstore进行大数据(大于256B)写

一般通过下面操作进行数据写入:store操作后,程序员可以通过clflush/clflushopt操作进行高速缓存evict或通过clwb操作进行写回(write back),以将数据写入至ADR域并最终写至Optane DIMM;或者,通过ntstore指令绕过高速缓存直接写入Optane DIMM。在进行完上述某种操作后,再进行sfence操作可确保先前的evict,write back和ntstore操作的数据变成持久的。写数据时,采用上述何种操作对性能影响很大。

Intel PMEM的使用经验和指南

图12 展示了顺序写操作的性能数据(图左为带宽,图右为延迟)。测试中,使用三种写方式:ntstore, store + clwb, 以及 store, 每次操作完后再进行一次 sfence操作。测试使用6个线程,因为该配置下所有的测试都能达到最好的性能。
对于写超过64B的数据,每store 64B进行cache的flush操作(相比于不进行flush操作)获得的带宽会更大(图12中的store+ clwb V.S. store)。我们认为,发生这种情况是因为,让高速缓存自然地换出缓存行,会给到达Optane DIMM的数据流增加不确定性。 主动换出缓存可确保访问保持顺序性。 EWR的值验证了该猜想:增加cache换出逻辑可以将EWR从0.26增加到0.98。
对于超过512 B的访问,ntstore的延迟比store + clwb更低(图12右)。对于超过256 B的访问,ntstore操作的带宽也最高(图12左)。这是因为: clwb必须在执行实际存储操作之前,其需将数据加载到CPU的本地高速缓存中,从而占用了Optane DIMM的部分带宽。 而ntstore通过绕过高速缓存,避免了这种不必要的读取,从而获得了更高的带宽。

Intel PMEM的使用经验和指南

图13显示了sfence如何影响性能。 测试时,使一个线程在Optane-NI上进行大小不同的顺序写操作。 在每个高速缓存行store操作后(每64B)或在整个写入store后(写入大小),进行clwb操作。 每个写操作后,再进行sfence操作,以确保整个写操作是持久的(上述整个过程称为一个“sfence间隔”)。 结果显示当写入大小为256 B时,带宽达到峰值(clflushopt对中等大小的写入进行了优化)。 在写入中等大小的数据后,再进行刷新操作不会影响带宽,但是当写入的大小超过8 MB时,写入后再进行刷新操作会导致性能下降,因为其导致了高速缓存容量的失效,从而使得EWR升高

限制访问Optane DIMM的并发线程数

系统应尽量减少同时访问单个DIMM的并发线程数。Optane DIMM有限的存储性能,以及iMC和Optane DIMM上有限的缓冲区共同限制了其同时处理多个线程请求的能力。 下面的两种竞争说明了,应限制访问Optane DIMM的并发线程数。

XPBuffer的竞争。对XPBuffer中缓存空间的争用将导致逐出次数增加,触发写3D-XPoint介质,这将使EWR降低。 图4(中)显示了这种效果:线程数增加时,性能无法扩展。 例如,与具有0.98的EWR的单线程相比,8线程进行顺序的ntstore操作,其EWR仅为0.62和带宽也只有69%。

iMC中的竞争。图15说明了,当多个核对单个DIMM操作时,iMC中有限的队列容量如何影响性能。该实验使用固定数量的线程(24个线程进行读,6个线程进行ntstore)对6个交错的Optane DIMM进行读/写操作。每个线程随机访问N个DIMM(线程间分布均匀)。随着N的增加,针对每个DIMM的写入次数会增加,但是每个DIMM的带宽会下降。可能的原因是XPBuffer的容量有限,但是EWR仍然非常接近1,因此性能问题肯定出在iMC中。

Intel PMEM的使用经验和指南

在我们测试平台中,单个线程多达256B的数据可在WPQ缓冲区中排队。我们的假设是,由于Optane DIMM的速度相比于读/写链路的其他部件很慢,因此WPQ中的数据消耗的很慢,而导致队头阻塞效应。N的增加会增加DIMM的争用,所以会增加“某个处理器因等待其之前的store操作完成而被阻塞”的可能性。
图5(右)展示了此现象的另一个示例:当对交错的Optane DIMM进行随机4 KB访问时,Optane带宽急剧下降。 Optane内存交错类似于磁盘阵列中的RAID-0:块大小为4 KB,条带大小为24 KB(一个内存插槽上的6个DIMM的每个都占用4 KB的连续块)。图5(右)中的工作负载的访问分布在这些交错的DIMM上,导致特定DIMM的竞争激增。
随着访问大小的增加,线程饥饿发生的更加频繁:在访问的大小等于交错的大小(4 kB)时,下降最为严重。对于大于交错大小的访问,每个核都开始将其访问分布在多个DIMM中,从而使得负载更加均匀。当写入的数据大小为24 kB和48 kB,出现了性能的小峰值,其访问在6个DIMM上完美分布。
只要在DIMM上不均匀地分布4 kB访问,就会出现这种性能下现象。同时,这可能是实践中的常见情况。例如,具有4 kB页的页缓存系统可能会表现不佳。

避免对远程NUMA节点的混合或多线程访问

Optane的NUMA效应远大于DRAM,因此应更加努力地避免跨插槽的存储器通信。对于读写混合且包含多线程访问的情况,其成本特别高。在本地和远程Optane内存之间,典型的读延迟差异分别为1.79倍(顺序)和1.20倍(随机)。对于写操作,远程Optane的延迟是本地的2.53倍(ntstore)和1.68倍。而对于带宽,远程Optane可以在最佳线程数下实现本地读/写带宽的59.2%和61.7%(本地读取为16,远程读取为10,本地和远程写入为4)。

上面的性能下降的比例类似于远程DRAM相较于本地DRAM。但是,当线程数增加或为读写混合负载时,Optane的带宽将急剧下降。根据我们扫描测试的结果,在相同工作负载下,远程Optane相比于本地的带宽差距可能超过30倍,而DRAM的只有3.3倍(未通过图展示具体数据)。

Intel PMEM的使用经验和指南

图17中,我们展示了调整读写比例会改变本地和远程访问Optane的带宽。图中展示了一个线程和四个线程的性能。针对所有测试的访问模式,本地Optane内存带宽随着线程数增加(增加到4)而增加。对于本地和远程访问,单线程带宽差距不大。而对于多线程访问,随着访问压力的提高,远程访问性能会更快下降,从而导致相对于本地访问而言性能较低。

上一篇:杂七杂八——使用LINQ检索重复值


下一篇:Nginx学习之开启Gzip压缩提升页面加载速度