Non-volatile random access memory (NVRAM) offers byte-addressable persistence at speeds comparable to DRAM. However, with caches remaining volatile, automatic cache evictions can reorder updates to memory, potentially leaving persistent memory in an inconsistent state upon a system crash. Flush instructions can be used to force ordering among updates, but are expensive. This has motivated significant work studying how to write correct and efficient persistent programs for NVRAM. In this paper, we present a programming interface, called the P-V Interface, describing the interaction of memory instructions that are crucial for persistence, and those for which flush instructions can be omitted. We show that the interface captures the desired semantics of many practical algorithms in the literature. Furthermore, we demonstrate that the P-V Interface admits efficient implementations, by introducing the FliT library, a C++ based library that implements the P-V Interface with easy-to-use, intuitive syntax. We apply the FliT library to four different persistent data structures, and show that across several workloads, persistence implementations, and data structure sizes, the FliT library always improves operation throughput, improving the performance of a basic persistent implementation by at least 2.1x in all but one workload.





Principles and Practice of Parallel Programming 2022