316
are relative to the beginning of the application’s virtual address space, but that comes
with many caveats. Using such pointers would be predicated on the pool of persistent
memory always being located at the same place in the virtual address space of an
application that maps it. This is difficult, if not impossible, to accomplish in a portable
way on modern operating systems due to address space layout randomization (ASLR).
Therefore, a general-purpose library for persistent memory programming must provide
a specialized persistent pointer. Figure 16-2 shows a pointer from Object A to Object B. If
the base address changes, the pointer no longer points to Object B.
An implementation of a general-purpose relative persistent pointer should satisfy
these two basic requirements:
1. The pointer must remain valid across application restarts.
2. The pointer should unambiguously identify a memory location in
the presence of many persistent memory pools, even if not located
in a pool from which it was originally derived.
In addition to the previous requirements, you should also consider some potential
performance problems:
• Additional space overhead over a traditional pointer. This is important
because large fat pointers would take up more space in memory and
because fewer of these fat pointers would fit in a single CPU cache line.
This potentially increases the cost of operations in pointer-chasing
heavy data structures, such as those found in B-tree algorithms.
• The cost of translating persistent pointers to real pointers. Because
dereferencing is an extremely common operation, this calculation
must be as lightweight as possible and should involve as few
instructions as possible. This is to ensure that persistent pointer
usage is efficient and it doesn’t generate too much code bloat during
compilation.
Figure 16-2. Example of using a normal pointer in a persistent memory pool
Chapter 16 pMDK Internals: IMportant algorIthMs anD Data struCtures
Précédent

- 340/457

Suivant