Nicolas van Kempen, Emery D. Berger
Programmers using native languages such as C, C++, or Rust can implement custom memory allocation strategies to improve execution time. This work revisits the influential "Reconsidering Custom Memory Allocation" paper almost 25 years later, on a modern hardware platform with modern general-purpose allocators. Our results support and extend the original conclusions, demonstrating the locality advantages of region-based custom memory allocators.
We initially named "littering" the technique introduced in the paper as "adversarial allocation". Therefore, you will find references to both in the text and code present in this repository.
To build the litterer, run the following commands.
cmake . -B build -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfo
cmake --build buildYou can then use it like so.
# First, run the detector to get a distribution of size classes.
LD_PRELOAD=./build/libdetector_distribution.so <PROGRAM>
# Then run the program.
env LD_PRELOAD=./build/liblitterer_distribution_standalone.so LITTER_MULTIPLIER=1 LITTER_OCCUPANCY=0.4 <PROGRAM>
# Compare performance by running without the litterer, or setting the multiplier to zero.
env LD_PRELOAD=./build/liblitterer_distribution_standalone.so LITTER_MULTIPLIER=0 <PROGRAM>The following litterer settings are available:
LITTER_DATA_FILENAME: for both the detector and litterer. Contains the name of the data file where to write/read the size class distribution. (default:distribution.json)LITTER_DETECTOR_APPEND: for the detector. Whether to append data to the given size class distribution file, or overwrite it. (default: no)LITTER_LOG_FILENAME: for the litterer. File where debug and result information will be logged. (default: stderr)LITTER_SEED: for the litterer. Seed to use during the random generation and disposal of allocated objects. (default: random seed)LITTER_OCCUPANCY: for the litterer. Fraction (between 0 and 1) of objects to keep on the heap after random allocation. (default: 0.95)LITTER_SHUFFLE: for the litterer. Whether to shuffle allocated objects before freeing a fraction of them. (default: yes)LITTER_SORT: for the litterer. Whether to sort allocated objects before freeing a fraction of them. (default: no)LITTER_SLEEP: for the litterer. Number of seconds to sleep after littering, but before starting the program. This is useful to attach a profiler for example. (default: 0)LITTER_MULTIPLIER: for the litterer. This number, multiplied by the maximum number of live allocations as measured by the detector, is the number of allocated objects during the littering process. (default: 20)
The following benchmarks are "documented" in this repo:
- 197.parser, 176.gcc, 175.vpr: See sample commands in SPEC2000.md. You will need a copy of the SPEC benchmarks.
- boxed-sim, mudlle: See sample commands in SPEC2000.md.
- blender: See sample commands in blender/BLENDER.md.
- rustc: See sample commands in rust/RUST.md.
- llvm/clang: Use docker/llvm.Dockerfile.
The graphs/run.py script may provide some additional documentation by example. It assumes that sources are present in the directory and built.