FAST'20
Jian Yang, Juno Kim, and Morteza Hoseinzadeh, UC San Diego; Joseph Izraelevitz, University of Colorado, Boulder; Steve Swanson, UC San Diego
研究背景
在之前很长一段时间内,针对NVM的相关研究都是将NVM当作一种“性能差一点的DRAM”这样的设备进行的,而当Intel正式发布了其Optane DC Persistent Memory(后称Optane DIMM)之后,研究人员发现,其各种特性与DRAM有着较大的区别,以至于之前对NVDIMM的性能以及特性的假设是错误的。本文的主题就是探究Optane DIMM的真实性能以及特性。本文从系统架构、基本性能开始,并给出了一些如何能够提升Optane DIMM使用效率的建议以及相关解释。
系统架构
Platform
iMC(intergrated memory controller)
Optane DIMM目前只支持Intel Cascade Lake处理器,一般来说每个处理器有1-2个processor die,每个processor die有两个iMC,一个iMC有3个channel(以Intel的服务器来说每个channel可以插两个DIMM),因此一个processor die最多可以支持6个Optane DIMM,Optane DIMM 可以直接插入内存总线并通过iMC访问
Intel的处理器有一个新的机制:ADR(Asynchronous DRAM Refresh),该机制主要用与确保数据在意外的情况下不丢失,当数据被写到ADR之后一定能够被刷写到Persistent Memory上。默认情况下ADR不会刷写CPU cache中的数据,部分平台支持eADR(Enhanced Asynchronous DRAM Refresh),这种情况下CPU cache也被包括到了ADR内,就不需要手动flush数据了(fence还是需要的)。
iMC内维护了读写队列:Read Pending Queue(RPQ)和Write Pending Queue(WPQ)用来对读写操作排序,而iMC位于ADR内,因此当store到达WPQ之后就能够确保数据不丢失。
iMC以cache line大小(64B)为粒度访问Optane DIMM。
对Optane DIMM的访问首先到on-DIMM controller,这个结构类似于SSD的FTL,主要作用是通过一个Addressing Indirection Table(AIT)进行wear-leveling和bad-block remapping。
3D-XPoint的访问粒度为一个XPLine大小(256B),因此小于256B的访问会被转换为一个256B的访问,造成读写放大,on-DIMM controller中有一个XPBuffer用于缓存读写操作,连续的小写可以被缓存到XPBuffer并进行merge,避免写放大。(XPBuffer位于ADR内,所以写入XPBuffer的数据已经持久化)
Operation Mode and Interleaving
Optane DIMM有两种operation mode:
- Memory mode:被用作一种更大的volatile内存来使用,与DRAM位于同一channel上并将DRAM作为cache
- AppDirect mode:被用作单独的非易失性内存
Interleaving:多个channel的DIMM通过一个类似raid-0的结构构成一个更大的整体,目前的interleaving大小为4KB,通过interleaving可以提升Optane DIMM的带宽。
以上图中六个Optane-DIMM的情况举例,小于4KB的访问一定会落在一个DIMM上,而大于24KB一定会访问所有的DIMM
指令集支持
目前可以通过ISA(Instruction Set Architeture)来访问Optane-DIMM,常用指令:
- clflush:将cache line无效化并写入memory
- clflushopt:同clflush,但是顺序限制上更小,并行性更好
- clwb:写回cache line但是cache line不会被淘汰
- ntstore:跳过CPU cache直接写memory
本文实验配置
- 24 core Cascade Lake Processor
- 1 CPU => 2 iMC => 6 memory channel
- 1 channel => 32GB memory + 256GB Optane DIMM
性能测试
LATTester
本文为了便于测试,开发了一个LATTester的测试工具,这个工具是一个内核工具,链接:https://github.com/NVSL/OptaneStudy
Typical Latency
测试方法:
Read:对顺序/随机位置的8B load
Write:load一个cache line,然后测试指令的延迟(分别是64B store + clwb + mfence中的clwb以及ntstore + mfence中的ntstore)
结果分析:
读延迟:Optane DIMM比DRAM高2-3倍,原因在于Optane介质本身访问较慢。Optane DIMM顺序随机性能相差80%,原因是XPBuffer对顺序读的缓存作用。
写延迟:无论是DRAM还是Optane-DIMM都是写到ADR就返回,因此写延迟接近,clwb比ntstore更快
Tail Latency
测试方法:测试tail latency与访问热点大小的关系,分配大小为N的circular buffer然后通过单线程执行20,000,000的64B写操作。
测试结果:随着hotspot region大小增加,出现latency spike的次数减少,但仍有少数50us左右的操作,这里本文作者也没有确定的原因,给出的一个猜测是wear-leveling引起的remapping。
Bandwidth
测试对象:bandwidth与线程数的关系,以及interleaving的影响
测试方法:
顺序读写:不同线程数下的256B顺序/随机访问,对于写操作分别测试clwb+mfence和ntstore,对于interleaved配置,每个操作都命中单个DIMM(因为page size是4K)
随机读写:测试不同访问粒度下的随机访问带宽,并采用性能最佳的线程数
测试结果:
- DRAM:带宽最高,并且随着线程数增加而提升,直到饱和,并且不受访问粒度大小影响;
- Optane-NI:最高读带宽是最高写带宽的2.9X,这个差距高于DRAM的1.3X;
- 线程数过多导致读写带宽降低。对于NI,1-4线程带宽最佳;对于Interleave下的store+clwb,12线程带宽最佳;
- 低于256B的访问带宽较低,原因是Optane介质256B的XPLine size;
- Interleaving对带宽的影响:
- Interleaveing提升了5.8X和5.6X的最高读写带宽,符合本文测试系统的DIMM个数(6个);
- 对于Interleaving:4KB出现一个低谷,原因是iMC的争用,这种情况在访问大小接近interleaving size(4KB)的时候最为明显,后面会具体分析。
与Emulation对比
结论:所有的模拟仿真方法都与Optane的真实表现有较大的差别
case study:RocksDB的优化
对比几种优化方法在模拟的pmem和真实Optane下的表现,其中Persistent Memtable是一个将memtable移到pmem减少WAL开销的优化,FLEX是将WAL移到pmem以加速WAL写的优化。结果表明在模拟的条件和真实Optane下,测试结果可能是相反的。(因为Persistent Memtable造成了更多的小写)
关于更好地使用Optane DIMM的相关建议
1. 避免小于256B的访问
一个直观的原因是:Optane-DIMM的访问粒度为256B,小于256B的访问会造成读写放大。
本文提出一个参数:EWR(Effective Write Ratio)
计算方法:iMC写的字节数 / 实际写到3D-XPoint介质上的字节数(实际上就是写放大的倒数,EWR小于1说明产生了写放大,大于1说明写操作被XPBuffer merge了)
测试结果表明EWR越大带宽越高,比如单线程ntstore的64B的随机访问EWR为0.25,而256B的访问的EWR是0.98
前面提到iMC访问的粒度是cache line的64B,但是这不会使256B的访问变得低效,因为有XPBuffer的存在,可以将64B的访问组合成一个大的256B的访问,所以说局部性好的小写性能会很好。
为了探究XPBuffer的容量本文也进行了测试。
测试方法:分配N XPLine,首先一次update每个XPLine的前半部分,然后update每个XPLine的后半部分,然后测试EWR
测试结果:当N=64(16KB)的时候,EWR基本维持不变,超过64之后写放大突增,说明超过了XPBuffer的容量,因此XPBuffer大约16KB,同时后面的测试也表明读操作也会争用XPBuffer。
结论:尽量避免小于256B的写,如果实在不能避免,尽可能限制访问数据在每个DIMM 16KB范围内
例子:上面的RocksDB测试中,PersistentMemtable性能更差,因为小访问更多
2. 对于大写用ntstore
ntstore:Non-Temporary Store,绕过CPU cache直接将数据写到Persistent Memory
测试方法:6线程,64B store,顺序访问
测试结果:
- store+clwb性能在大于64B之后优于单store,原因是让系统自己去淘汰增加了不确定性,可能影响访问的顺序,而主动淘汰可以保证访问的顺序;
- 访问大于512B之后,ntstore的延迟比store+clwb的延迟低,原因是store+clwb需要将数据从介质load到CPU cache,而ntstore避免了这次读,因此延迟更低并且实现了更高的带宽。
测试方法:测试sfence的位置对带宽的影响,在单线程 / Optane-NI / 顺序写的情况下,分别测试不同的写粒度下每写64B就sfence以及整个写完了再sfence的带宽
测试结果:
- 256B的时候达到带宽峰值
- sfence的位置不影响性能,超过8MB的时候因为超过cache容量会引起性能下降
case study:PMDK micro-buffering
micro-buffering是用于事务更新持久对象的技术,该技术在事务开始之前首先将对象从Optane拷贝到DRAM,等提交的时候通过ntstore一次性写回。测试对比了原来的micro-buffering以及对小对象使用一般的store+flush指令的版本,发现后者在1KB之前的延迟更低。
3. 限制并发访问单个Optane DIMM的线程数
XPBuffer的争用
多线程争用XPBuffer可能会使数据频繁淘汰到介质,降低EWR,如图4中间,8线程的EWR为0.62,此时带宽是单线程的69%,EWR为0.98
iMC的争用
测试内容:iMC的queue capacity对多线程性能的限制
测试方法:用固定的线程数(24 read / 6 write)访问6 interleaved Optane,让每个线程访问随机N个DIMM
测试结果:随着N增加,带宽降低
分析:从WPQ淘汰Optane较慢,因此可能会因为队首的请求而阻塞后面的请求,增加线程访问DIMM个数,就增加了被阻塞的概率。图5中多线程访问Interleaved Optane DIMM的时候,也会因为多线程争用单个DIMM造成性能下降。图5里面访问粒度超过4K之后,单个线程可能访问多个DIMM,同样会造成争用。
4. 避免NUMA Access
多线程的load/store混合访问remote的Optane开销较大,性能差距最高可以达到30X
对于多线程访问,随着写比例增加,remote访问的性能下降更加厉害