207
© The Author(s) 2020
S. Scargall, Programming Persistent Memory, https://doi.org/10.1007/978-1-4842-4932-1_12
CHAPTER 12
Debugging Persistent
Memory Applications
Persistent memory programming introduces new opportunities that allow developers to
directly persist data structures without serialization and to access them in place without
involving classic block I/O. As a result, you can merge your data models and avoid the
classic split between data in memory – which is volatile, fast, and byte addressable – with
data on traditional storage devices, which is non-volatile but slower.
Persistent memory programming also brings challenges. Recall our discussion
about power-fail protected persistence domains in Chapter 2: When a process or system
crashes on an Asynchronous DRAM Refresh (ADR)-enabled platform, data residing in
the CPU caches that has not yet been flushed, is lost. This is not a problem with volatile
memory because all the memory hierarchy is volatile. With persistent memory, however,
a crash can cause permanent data corruption. How often must you flush data? Flushing
too frequently yields suboptimal performance, and not flushing often enough leaves the
potential for data loss or corruption.
Chapter 11 described several approaches to designing data structures and using
methods such as copy-on-write, versioning, and transactions to maintain data integrity.
Many libraries within the Persistent Memory Development Kit (PMDK) provide
transactional updates of data structures and variables. These libraries provide optimal
CPU cache flushing, when required by the platform, at precisely the right time, so you
can program without concern about the hardware intricacies.
This programming paradigm introduces new dimensions related to errors and
performance issues that programmers need to be aware of. The PMDK libraries reduce
errors in persistent memory programming, but they cannot eliminate them. This chapter
© The Author(s) 2020
S. Scargall, Programming Persistent Memory, https://doi.org/10.1007/978-1-4842-4932-1_12
CHAPTER 12
Debugging Persistent
Memory Applications
Persistent memory programming introduces new opportunities that allow developers to
directly persist data structures without serialization and to access them in place without
involving classic block I/O. As a result, you can merge your data models and avoid the
classic split between data in memory – which is volatile, fast, and byte addressable – with
data on traditional storage devices, which is non-volatile but slower.
Persistent memory programming also brings challenges. Recall our discussion
about power-fail protected persistence domains in Chapter 2: When a process or system
crashes on an Asynchronous DRAM Refresh (ADR)-enabled platform, data residing in
the CPU caches that has not yet been flushed, is lost. This is not a problem with volatile
memory because all the memory hierarchy is volatile. With persistent memory, however,
a crash can cause permanent data corruption. How often must you flush data? Flushing
too frequently yields suboptimal performance, and not flushing often enough leaves the
potential for data loss or corruption.
Chapter 11 described several approaches to designing data structures and using
methods such as copy-on-write, versioning, and transactions to maintain data integrity.
Many libraries within the Persistent Memory Development Kit (PMDK) provide
transactional updates of data structures and variables. These libraries provide optimal
CPU cache flushing, when required by the platform, at precisely the right time, so you
can program without concern about the hardware intricacies.
This programming paradigm introduces new dimensions related to errors and
performance issues that programmers need to be aware of. The PMDK libraries reduce
errors in persistent memory programming, but they cannot eliminate them. This chapter
