ITPub博客

首页 > 数据库 > 数据库开发技术 > 持久内存编程

持久内存编程

翻译 数据库开发技术 作者:yzs87 时间:2020-04-05 20:42:01 0 删除 编辑

持久内存编程

2013 6 月我写了关于非易失性内存( NVM )的未来接口。其中描述了 SNIA NVM Programming technical work group TWG )正在开发的 NVM 编程模型。在过去的四年里,规范已经发布,正如预测的那样,编程模型已成为大量后续工作的重点。该编程模型,在规范中描述为 NVM.PM.FILE ,可以将 PM 当做文件被操作系统映射到内存。本文,介绍持久内存编程模型如何在操作系统中实现,已经做了哪些工作,以及我们还面临着哪些挑战。

持久内存背景

PM storage class memory 是同一的术语,具有字节寻址、加载 / 存储内存访问特性,但具备持久性。本文,关注将 PM 挂在系统内存总线上,例如 DRAM DIMM ,创建一类称为 NVDIMMs 的非易失 DIMMs

为进一步阐述所说的持久内存是什么,仅讨论NVDIMMs ,允许软件像访问内存一样访问。提供了内存语义的所有优点,例如 CPU CACHE 一致性、其他设备直接内存访问 DMA 、缓冲线粒度访问,即可字节寻址。为提供这些语义,设备必须足够块以便指令访问 CPU 时拖延 CPU 合情合理。 NAND flash 当做持久内存时比较慢,因为需要以块为单位进行访问,并需要足够长的时间进行上下文切换。硬件访问的时间通常以毫秒为单位, NAND Flash SSD 以微妙为单位, PM 以纳秒为单位。依赖于硬件媒体类型, NVDIMM 可能速度还比不上 DRAM ,但是速度已经堪比他的速度了。

现在市场上的一些NVDIMM 产品,运行时使用 DRAM 作为媒介,断电时自动将内容备份到 NAND Flash ,再次上电时将 NAND Flash 内容返回 DRAM 。这些产品提供 DRAM 的性能,但是需要额外的部件和电池来存储数据,相比 DRAM ,为每个 DIMM 提供小容量、每 G 高消耗的特性。新出现的非易失性媒介,例如 2015 年, Intel 和美光联合研发的 3D XPoint 技术,通过比 DRAM 更高的容量。每个 CPU 达到上 T 的带宽,使持久内存引起多方前沿关注:持久性、容量、消耗。

持久内存编程模型

如何是应用访问持久内存?和易失性内存不同,应用需要特定方法和指定的持久内容连接;持久内存不像易失性内存一样是匿名的,他需要像文件一样命名一个区域,这样应用才能找到他。应用需要具有访问持久内存的控制权限。推荐SNIA TWG 编程模型是因为操作系统可以使用标准的文件语义提供持久内存的命名、权限和内存映射。

当前,多种操作系统包括Linux Windows 都支持了这种模型。

 

 

DAX

Figure 1 中显示的持久内存适配的文件系统,允许直接访问持久内存,而不经过系统的 page cache 。这样的特性称为 DAX 。持久内存编程模型和 DAX 特性表明持久内存文件可以使用 mmap() MapViewOfFile() 类似的标志函数映射到内存。这种类型时图 1 最右边形式。应用直接通过 load/store 指令访问持久内存。允许直接访问持久媒介而不用进行用户态和内核态的切换。

存储持久化

Linux 系统可以使用 msync() fsync() 确保数据持久化, Windows 可以通过 FlushViewOfFile() FlushFileBuffers() 确保数据持久化。这些调用会创建一个内存栅,这个点之前的数据都已经全部持久化到持久内存。历史上,这个存储栅需要操作系统找到 page cache 中的脏页,然后将他们刷写到磁盘。由于持久内存不使用 page cache ,操作系统仅需要将 CPU cache 中的变动刷写到持久内存。如图 2 所示:

 

2 中虚线部分显示了持久域。这种级别的架构,虚线部分的数据要么在 DIMM ,要么咋内存控制器的写请求队列 WPQ 。无论哪种返回,持久内存需要有足够的电量将虚线框中的数据刷写到持久媒介。这种特性叫做异步 DRAM 刷,并 NVDIMM 已经具备这种特性。

X86 架构中,简单执行存储指令并不能确保数据持久化,因为数据可能仍然在 CPU cache ,一旦断电,这些数据就会丢失。需要额外的刷写指令确保数据持久化。下表描述了他们如何工作。

2 和表 1 中可能会使人迷惑,为什么 Intel 不将 CPU cache 弄到持久域部分。技术上可行,图 2 中的虚线框内包括 CPU CACHEs

扩展持久域包括CPU CACHEs 的问题是 x86 caches 非常大,他需要的电量比电容器实际能提供的电量多的多。这就意味着平台需要电池。此时支持持久内存的服务器都配一个电池不太现实。但是对于硬件供应商来说,当然有可能在其商品中包含一个电池。这就允许跳过表 1 中描述读缓冲刷新指令,但是 sfence 指令仍然是必须的,因为存储屏障存储只有在全局可见时才被认为是持久的,这就是 sfence 确保的。

因为应用供应商计划使用电池以及未来期望所有平台都将CPU cache 包含到持久域,所以在 ACPI 中添加一个属性,这样当跳过 CPU 刷时, BIOS 可以通知操作系统。这就允许操作系统以最优的方式实现类似 msync 的调用。

刷写用户空间到持久域

WBINVD 例外, Intel CPU 以用户态模式支持表 1 中描述的指令。使用 CLWB CLFLUSHOT CLFLUSH )刷写 cache line 并支持用用户态使用临时存储。

 

这就允许从用户空间刷写到持久内存,而不需要经过内核,这个特性称为Optimized Flush 。依赖于操作系统和硬件,各个平台选择性支持这个特性。尽管有 CPU 支持,但是对于应用程序来说只有操作系统说安全时才使用 optimized flush 。当文件系统元数据改变需要 msync 刷写时,操作系统需要这个控制点。

当前实现中支持安全的用户空间刷正不断演化。Windows DAX NTFS 文件系统提供,包括无条件支持 Optimized flush Windows 使用类似 CLWB+SFENCE 的指令保持数据持久化到持久内存。 Linux 中的 ext4 xfs 支持 DAX ,不需要考虑用户空间刷写安全性。作为临时解决方案, Linux 提供 Device-DAx ,允许应用打开持久内存设备,将其映射到内存,利用用户空间刷写确保持久性。

Libpmem 库提供函数告诉应用程序何时 Optimized flush 是安全的。强烈建议程序员使用 libpmem 来确定并使用用户空间刷写。 Libpmem 也被用来检测平台使用电池的情况,将刷写调用转换成简单的 sfence 指令调用。下文会详细介绍这个库。

持久内存挑战

内存中数据结构改变时原子性问题就出现了。其他线程访问这个数据结构时会不会仅考到修改到一半的数据?多线程编程时通常使用锁来保护数据结构。有时也会使用指令确保硬件中的原子性。本文中原子性也成为可见性,当修改提交时,另外一个线程才能看到这个线程的修改。

 

Libpmemobj 库提供事务保证,确保断电安全。在持久内存出现前,断电等中断写时,内存状态不会出现问题,因为是易失的。但是持久内存中,需要理解部分状态刷后就已经持久化。 Intel 仅使用 8 字节存储确保故障原子性。大于 8 字节的将不保证数据一致性。

其他挑战:管理空间。因为持久内存域被当做文件,文件系统可以管理这个空间,但是一旦被应用映射到内存,文件中发生的事情完全取决于应用。和malloc 类似的函数分配的内存是易失的,在重启时不提供方法重连持久内存对,也不辞去任何步骤保证出现故障时数据一致性。所以持久内存编程中也需要着重处理空间分配问题。

地址独立性是另一个挑战。尽管技术上可以实现持久内映射到同一个地址上,但是当其他映射items 大小改变时,这就不切实际了。一种地址空间布局随机化的特性会使操作系统随机调整库和文件映射地址。地址独立意味着持久内存中数据结构引用另一个使用指针的数据结构,即使文件映射到不同地址,这个指针也必须以某种方式使用。有几种方法实现这一点,例如在映射后重新定位指针,使用相对指针而不是绝对指针,或者使用某种类型的对象 ID 来应用驻存在持久内存中的数据结构。

NVM库

Intel 开发的 pmdk 库,在 GitHub 上开源,开源协议 BSD ,使用手册可从 http://pmem.io 查看。

libpmem :基本库

这个库比较小,相对简单,包含探测CPU 支持哪种刷写指令以及使用最佳指令进行范围拷贝。

libpmemobj :支持事务

Libpmemblk libpmemlog :支持特定用户案例

Libmemkind :持久内存易失性使用

总结

2013 年的 ideas 成熟了并加到了完整的编程模型中。 Pmdk 库被开发出来,以供持久内存编程使用。该库在 GitHub 上开源 https://github.com/pmem

原文

https://www.snia.org/pm-summit2019

https://www.snia.org/pm-summit2017


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/31493717/viewspace-2684583/,如需转载,请注明出处,否则将追究法律责任。

下一篇: WAL文件回收
全部评论
专注于MySQL、Aerospike、PostgreSQL数据库

注册时间:2017-10-03

  • 博文量
    104
  • 访问量
    81865