持久内存BTT实现及优化(二)

Intel IOG/PRC Optane CoE

Wu, Dennis ([email protected])

一般提示及法律声明:

本主题主要涉及Linux内核BTT的优化,该优化将遵循开源的原则,所有的代码公开。实际测试的性能受使用情况、配置和其他因素的差异影响。

目录

1、介绍

2、电源故障保护域

3、用户态和内核态的性能


1、介绍

 我们已经在上一篇文章中介绍过持久内存BTT的原理,实现以及算法的优化,相关的内核patch也正在提交审阅[i],你也可以直接在我个人的github上去编译[ii]。上篇文章中还罗列了一些相关的后续工作,其中一个是PMDK中的libpmemblk也使用了BTT相关算法,所以也可以采用该优化, 其中优化的代码正在提交审阅[iii]
在测试的过程中,我们发现用户态BTT的性能要远好于内核态的性能。根本原因是由于在kernel BTT中使用了deep flush, 这个操作会将内存控制器写入队列(Write Pending Queue, WPQ)中的数据,写入到持久内存控制器。这个操作非常重,影响到整个内核的BTT的性能。
static int nsio_rw_bytes(struct nd_namespace_common *ndns,
        resource_size_t offset, void *buf, size_t size, int rw,
        unsigned long flags)
{
  ...
    memcpy_flushcache(nsio->addr + offset, buf, size);
    /* 
     * call nvdimm_flush, fense + deep flush will flush the WPQ
     * into PMem; if we levearge ADR, we just need to call fense
     * to make sure the data in the memory controller WPQ.
     */
ret = nvdimm_flush(to_nd_region(ndns->dev.parent), NULL);
    if (ret)
    	rc = ret;
    return rc;
}

Figure 1 Kernel BTT写数据使用了deep flush

2、电源故障保护域

        一个计算机系统可能包含一个或多个CPU、易失性的内存模块、持久内存模块和非易失性存储设备,如固态盘或机械硬盘。系统平台硬件支持持久域的概念,即电源故障保护域。根据平台的不同,持久域可能包括持久内存控制器和其写入队列、内存控制器写入队列以及 CPU 高速缓存。数据到达持久域后,在系统重新启动的过程中,数据是可以恢复的。也就是说,如果数据位于受电源故障保护的硬件写入队列或缓冲区内,应用可以认为这些数据已经持久化了。例如,如果发生断电,将使用储存电量从电源故障保护域中刷新数据,平台应保证此操作的电力供应。未达到保护域的数据将丢失。

        在计算机系统断电后,易失性内存将丢失其内容。与非易失性存储设备一样,持久内存即使在系统断电时也能保留其内容。

        异步内存刷新 (Asynchronous DRAM Refresh, ADR) 是英特尔产品支持的一项特性,可刷新写保护的数据缓冲区并将内存置于自刷新状态。该进程在断电或系统崩溃期间至关重要,可确保数据在持久内存上处于安全、一致的状态。默认情况下,ADR 不会刷新处理器高速缓存。支持 ADR 的平台仅包含持久内存和持久域中内存控制器的写入挂起队列(Write Pending Queue, WPQ)。因此,应用必须使用 CLWB、CLFLUSHOPT、CLFLUSH、非临时存储(Non-Temporal store, NTW)或 WBINVD 机器指令刷新CPU高速缓存中的数据。

        增强异步内存刷新 (enhanced ADR, eADR) 要求调用不可屏蔽中断 (NMI) 例程,以便在 ADR 事件开始之前刷新 CPU 高速缓存。在 eADR 平台上运行的应用不需要执行刷新操作,因为硬件应自动刷新数据,但是它们仍需执行 SFENCE 操作,以确保正确的写入顺序。只有 SFENCE 支持的全局可见存储才被视为持久存储。Figure 1显示了ADR和eADR持久域。

        ADR 是持久内存在平台方面的一个强制性要求。写入数据后,内存控制器中的写入挂起队列 (WPQ) 确认收到数据。虽然数据尚未到达持久介质,但是支持 ADR 的平台可确保在发生断电事件时能够成功写入数据。在系统崩溃或断电期间,只有平台支持 eADR,才能保证CPU 高速缓存中的数据可以被刷新至持久介质。如果平台仅支持 ADR,CPU高速缓存中的数据将丢失。

        将 CPU 高速缓存纳入持久域的挑战在于 CPU 高速缓存非常大,其消耗的电量远高于一般电源中电容实际上可以提供的电量。因此,平台需要包含电池或利用外部不间断电源。为支持持久内存的每台服务器配备一块电池一般来说不现实,且价格高昂。电池的生命周期通常比服务器要短,这将产生额外的维护任务,从而降低服务器的正常运行时间。使用电池还会对环境造成影响,因为必须正确地处置或回收电池。服务器或设备 OEM 在其产品中配备电池是完全可行的。

        由于某些设备和服务器厂商计划使用电池,并且平台未来将把 CPU 高速缓存纳入持久域,因此 ACPI 提供了一种属性,允许 BIOS 在CPU 刷新被跳过时通知软件。在包含 eADR 的平台上,无需手动刷新高速缓存行。

持久内存BTT实现及优化(二)_第1张图片

Figure 2 ADR和eADR 电源故障保护域

3、用户态和内核态的性能

        Deep Flush是系统最严格的持久化的需求,将内存控制器WPQ的数据主动刷新到持久内存中,而不是依赖ADR的功能在系统断电的情况想将内存控制器WPQ的数据刷新到持久内存。为了解决这个问题,一个新的kernel patch可以用户来控制是否需要使用deep flush。考虑到有些客户可能不会去主动去控制deep flush,所以我们又在BTT中增加了一个flag[iv]来控制BTT中deep flush的使用,使得BTT在运行时不会使用deep flush从而影响BTT的性能。如果不需要使用deep flush,性能会有一个大幅的提升。如果大家有兴趣,可以使用这些patch来获得性能的提升。

 

[i][PATCH] BTT: Use dram freelist and remove bflog to otpimize perf

[ii]GitHub - guoanwu/linux: Linux kernel source tree 和GitHub - guoanwu/linux at kernel5.4

[iii]https://github.com/pmem/pmdk/pull/5444

[iv][PATCH] ACPI/NFIT: Add no_deepflush param to dynamic control flush operation

你可能感兴趣的:(java,开发语言)