Git Product home page Git Product logo

snmalloc's Introduction

snmalloc

snmalloc is a research allocator. Its key design features are:

  • Memory that is freed by the same thread that allocated it does not require any synchronising operations.
  • Freeing memory in a different thread to initially allocated it, does not take any locks and instead uses a novel message passing scheme to return the memory to the original allocator, where it is recycled.
  • The allocator uses large ranges of pages to reduce the amount of meta-data required.

Details about snmalloc's design can be found in the accompanying paper. Differences between the paper and the current implementation are described here.

Build Status

Building on Windows

The Windows build currently depends on Visual Studio 2017. To build with Visual Studio:

mkdir build
cd build
cmake -G "Visual Studio 15 2017 Win64" ..
cmake --build . --config Debug
cmake --build . --config Release
cmake --build . --config RelWithDebInfo

You can also omit the last three steps and build from the IDE. Visual Studio builds use a separate directory to keep the binaries for each build configuration.

Alternatively, you can follow the steps in the next section to build with Ninja using the Visual Studio compiler.

Building on UNIX-like platforms

snmalloc has platform abstraction layers for XNU (macOS, iOS, and so on), FreeBSD, NetBSD, OpenBSD, and Linux and is expected to work out of the box on these systems. Please open issues if it does not. Note that NetBSD, by default, ships with a toolchain that emits calls to libatomic but does not ship libatomic. To use snmalloc on NetBSD, you must either acquire a libatomic implementation (for example, from the GCC or LLVM project) or compile with clang.

snmalloc has very few dependencies, CMake, Ninja, Clang 6.0 or later and a C++17 standard library. Building with GCC is currently not recommended because GCC emits calls to libatomic for 128-bit atomic operations.

To build a debug configuration:

mkdir build
cd build
cmake -G Ninja .. -DCMAKE_BUILD_TYPE=Debug
ninja

To build a release configuration:

mkdir build
cd build
cmake -G Ninja .. -DCMAKE_BUILD_TYPE=Release
ninja

To build with optimizations on, but with debug information:

mkdir build
cd build
cmake -G Ninja .. -DCMAKE_BUILD_TYPE=RelWithDebInfo
ninja

On ELF platforms, the build produces a binary libsnmallocshim.so. This file can be LD_PRELOADed to use the allocator in place of the system allocator, for example, you can run the build script using the snmalloc as the allocator for your toolchain:

LD_PRELOAD=/usr/local/lib/libsnmallocshim.so ninja

CMake Feature Flags

These can be added to your cmake command line.

-DUSE_SNMALLOC_STATS=ON // Track allocation stats
-DUSE_MEASURE=ON // Measure performance with histograms

Using snmalloc as header-only library

In this section we show how to compile snmalloc into your project such that it replaces the standard allocator functions such as free and malloc. The following instructions were tested with CMake and Clang running on Ubuntu 18.04.

Add these lines to your CMake file.

set(SNMALLOC_ONLY_HEADER_LIBRARY ON)
add_subdirectory(snmalloc EXCLUDE_FROM_ALL)

In addition make sure your executable is compiled to support 128 bit atomic operations. This may require you to add the following to your CMake file.

target_link_libraries([lib_name] PRIVATE snmalloc_lib)

You will also need to compile the relevant parts of snmalloc itself. Create a new file with the following contents and compile it with the rest of your application.

#define NO_BOOTSTRAP_ALLOCATOR

#include "snmalloc/src/override/malloc.cc"

Porting snmalloc to a new platform

All of the platform-specific logic in snmalloc is isolated in the Platform Abstraction Layer (PAL). To add support for a new platform, you will need to implement a new PAL for your system.

The PAL must implement the following methods:

void error(const char* const str) noexcept;

Report a fatal error and exit.

void notify_not_using(void* p, size_t size) noexcept;

Notify the system that the range of memory from p to p + size is no longer in use, allowing the underlying physical pages to recycled for other purposes.

template<ZeroMem zero_mem>
void notify_using(void* p, size_t size) noexcept;

Notify the system that the range of memory from p to p + size is now in use. On systems that lazily provide physical memory to virtual mappings, this function may not be required to do anything. If the template parameter is set to YesZero then this function is also responsible for ensuring that the newly requested memory is full of zeros.

template<bool page_aligned = false>
void zero(void* p, size_t size) noexcept;

Zero the range of memory from p to p + size. This may be a simple memset call, but the page_aligned template parameter allows for more efficient implementations when entire pages are being zeroed. This function is typically called with very large ranges, so it may be more efficient to request that the operating system provides background-zeroed pages, rather than zeroing them synchronously in this call

template<bool committed>
void* reserve(size_t* size, size_t align);
template<bool committed>
void* reserve(const size_t* size) noexcept;

Only one of these needs to be implemented, depending on whether the underlying system can provide strongly (e.g. 16MiB) aligned memory regions. If the system guarantees only page alignment, implement the second and snmalloc will over-allocate and then trim the requested region. If the system provides strong alignment, implement the first to return memory at the desired alignment.

Finally, you need to define a field to indicate the features that your PAL supports:

static constexpr uint64_t pal_features = ...;

These features are defined in the PalFeatures enumeration.

There are several partial PALs that can be used when implementing POSIX-like systems:

  • PALPOSIX defines a PAL for a POSIX platform using no non-standard features.
  • PALBSD defines a PAL for the common set of BSD extensions to POSIX.
  • PALBSD_Aligned extends PALBSD to provide support for aligned allocation from mmap, as supported by NetBSD and FreeBSD.

Each of these template classes takes the PAL that inherits from it as a template parameter. A purely POSIX-compliant platform could have a PAL as simple as this:

class PALMyOS : public PALPOSIX<PALMyOS> {}

Typically, a PAL will implement at least one of the functions outlined above in a more-efficient platform-specific way, but this is not required. Non-POSIX systems will need to implement the entire PAL interface. The Windows, and OpenEnclave and FreeBSD kernel implementations give examples of non-POSIX environments that snmalloc supports.

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.

When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

snmalloc's People

Contributors

mjp41 avatar davidchisnall avatar nwf avatar theodus avatar rschust avatar devnexen avatar plietar avatar microsoftopensource avatar ashamis-ms avatar msftgits avatar ricleite avatar schrodingerzhu avatar

Watchers

James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.