• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

bin/H03-May-2022-

cmake/H15-Nov-2021-3128

doc/H03-May-2022-3,8402,203

docs/H03-May-2022-2,2981,926

ide/H15-Nov-2021-2,7672,762

include/H15-Nov-2021-2,5141,715

src/H15-Nov-2021-10,6917,685

test/H03-May-2022-1,332978

.gitattributesH A D15-Nov-2021196 1211

.gitignoreH A D15-Nov-2021115 98

LICENSEH A D15-Nov-20211.1 KiB2217

azure-pipelines.ymlH A D15-Nov-20214.9 KiB182175

readme.mdH A D15-Nov-202137.8 KiB697549

readme.md

1
2<img align="left" width="100" height="100" src="doc/mimalloc-logo.png"/>
3
4[<img align="right" src="https://dev.azure.com/Daan0324/mimalloc/_apis/build/status/microsoft.mimalloc?branchName=dev"/>](https://dev.azure.com/Daan0324/mimalloc/_build?definitionId=1&_a=summary)
5
6# mimalloc
7
8&nbsp;
9
10mimalloc (pronounced "me-malloc")
11is a general purpose allocator with excellent [performance](#performance) characteristics.
12Initially developed by Daan Leijen for the run-time systems of the
13[Koka](https://koka-lang.github.io) and [Lean](https://github.com/leanprover/lean) languages.
14
15Latest release tag: `v2.0.3` (beta, 2021-11-14).
16Latest stable  tag: `v1.7.3` (2021-11-14).
17
18mimalloc is a drop-in replacement for `malloc` and can be used in other programs
19without code changes, for example, on dynamically linked ELF-based systems (Linux, BSD, etc.) you can use it as:
20```
21> LD_PRELOAD=/usr/lib/libmimalloc.so  myprogram
22```
23It also has an easy way to override the default allocator in [Windows](#override_on_windows). Notable aspects of the design include:
24
25- __small and consistent__: the library is about 8k LOC using simple and
26  consistent data structures. This makes it very suitable
27  to integrate and adapt in other projects. For runtime systems it
28  provides hooks for a monotonic _heartbeat_ and deferred freeing (for
29  bounded worst-case times with reference counting).
30- __free list sharding__: instead of one big free list (per size class) we have
31  many smaller lists per "mimalloc page" which reduces fragmentation and
32  increases locality --
33  things that are allocated close in time get allocated close in memory.
34  (A mimalloc page contains blocks of one size class and is usually 64KiB on a 64-bit system).
35- __free list multi-sharding__: the big idea! Not only do we shard the free list
36  per mimalloc page, but for each page we have multiple free lists. In particular, there
37  is one list for thread-local `free` operations, and another one for concurrent `free`
38  operations. Free-ing from another thread can now be a single CAS without needing
39  sophisticated coordination between threads. Since there will be
40  thousands of separate free lists, contention is naturally distributed over the heap,
41  and the chance of contending on a single location will be low -- this is quite
42  similar to randomized algorithms like skip lists where adding
43  a random oracle removes the need for a more complex algorithm.
44- __eager page reset__: when a "page" becomes empty (with increased chance
45  due to free list sharding) the memory is marked to the OS as unused ("reset" or "purged")
46  reducing (real) memory pressure and fragmentation, especially in long running
47  programs.
48- __secure__: _mimalloc_ can be built in secure mode, adding guard pages,
49  randomized allocation, encrypted free lists, etc. to protect against various
50  heap vulnerabilities. The performance penalty is usually around 10% on average
51  over our benchmarks.
52- __first-class heaps__: efficiently create and use multiple heaps to allocate across different regions.
53  A heap can be destroyed at once instead of deallocating each object separately.
54- __bounded__: it does not suffer from _blowup_ \[1\], has bounded worst-case allocation
55  times (_wcat_), bounded space overhead (~0.2% meta-data, with at most 12.5% waste in allocation sizes),
56  and has no internal points of contention using only atomic operations.
57- __fast__: In our benchmarks (see [below](#performance)),
58  _mimalloc_ outperforms other leading allocators (_jemalloc_, _tcmalloc_, _Hoard_, etc),
59  and often uses less memory. A nice property
60  is that it does consistently well over a wide range of benchmarks. There is also good huge OS page
61  support for larger server programs.
62
63The [documentation](https://microsoft.github.io/mimalloc) gives a full overview of the API.
64You can read more on the design of _mimalloc_ in the [technical report](https://www.microsoft.com/en-us/research/publication/mimalloc-free-list-sharding-in-action) which also has detailed benchmark results.
65
66Enjoy!
67
68### Branches
69
70* `master`: latest stable release.
71* `dev`: development branch for mimalloc v1.
72* `dev-slice`: development branch for mimalloc v2 with a new algorithm for managing internal mimalloc pages.
73
74### Releases
75
76Note: the `v2.x` beta has a new algorithm for managing internal mimalloc pages that tends to use reduce memory usage
77  and fragmentation compared to mimalloc `v1.x` (especially for large workloads). Should otherwise have similar performance
78  (see [below](#performance)); please report if you observe any significant performance regression.
79
80* 2021-11-14, `v1.7.3`, `v2.0.3` (beta): improved WASM support, improved macOS support and performance (including
81  M1), improved performance for v2 for large objects, Python integration improvements, more standard
82  installation directories, various small fixes.
83
84* 2021-06-17, `v1.7.2`, `v2.0.2` (beta): support M1, better installation layout on Linux, fix
85  thread_id on Android, prefer 2-6TiB area for aligned allocation to work better on pre-windows 8, various small fixes.
86
87* 2021-04-06, `v1.7.1`, `v2.0.1` (beta): fix bug in arena allocation for huge pages, improved aslr on large allocations, initial M1 support (still experimental).
88
89* 2021-01-31, `v2.0.0`: beta release 2.0: new slice algorithm for managing internal mimalloc pages.
90
91* 2021-01-31, `v1.7.0`: stable release 1.7: support explicit user provided memory regions, more precise statistics,
92  improve macOS overriding, initial support for Apple M1, improved DragonFly support, faster memcpy on Windows, various small fixes.
93
94### Older Releases
95
96* 2020-09-24, `v1.6.7`: stable release 1.6: using standard C atomics, passing tsan testing, improved
97  handling of failing to commit on Windows, add [`mi_process_info`](https://github.com/microsoft/mimalloc/blob/master/include/mimalloc.h#L156) api call.
98* 2020-08-06, `v1.6.4`: stable release 1.6: improved error recovery in low-memory situations,
99  support for IllumOS and Haiku, NUMA support for Vista/XP, improved NUMA detection for AMD Ryzen, ubsan support.
100* 2020-05-05, `v1.6.3`: stable release 1.6: improved behavior in out-of-memory situations, improved malloc zones on macOS,
101  build PIC static libraries by default, add option to abort on out-of-memory, line buffered statistics.
102* 2020-04-20, `v1.6.2`: stable release 1.6: fix compilation on Android, MingW, Raspberry, and Conda,
103  stability fix for Windows 7, fix multiple mimalloc instances in one executable, fix `strnlen` overload,
104  fix aligned debug padding.
105* 2020-02-17, `v1.6.1`: stable release 1.6: minor updates (build with clang-cl, fix alignment issue for small objects).
106* 2020-02-09, `v1.6.0`: stable release 1.6: fixed potential memory leak, improved overriding
107  and thread local support on FreeBSD, NetBSD, DragonFly, and macOSX. New byte-precise
108  heap block overflow detection in debug mode (besides the double-free detection and free-list
109  corruption detection). Add `nodiscard` attribute to most allocation functions.
110  Enable `MIMALLOC_PAGE_RESET` by default. New reclamation strategy for abandoned heap pages
111  for better memory footprint.
112* 2020-02-09, `v1.5.0`: stable release 1.5: improved free performance, small bug fixes.
113* 2020-01-22, `v1.4.0`: stable release 1.4: improved performance for delayed OS page reset,
114more eager concurrent free, addition of STL allocator, fixed potential memory leak.
115* 2020-01-15, `v1.3.0`: stable release 1.3: bug fixes, improved randomness and [stronger
116free list encoding](https://github.com/microsoft/mimalloc/blob/783e3377f79ee82af43a0793910a9f2d01ac7863/include/mimalloc-internal.h#L396) in secure mode.
117* 2019-12-22, `v1.2.2`: stable release 1.2: minor updates.
118* 2019-11-22, `v1.2.0`: stable release 1.2: bug fixes, improved secure mode (free list corruption checks, double free mitigation). Improved dynamic overriding on Windows.
119* 2019-10-07, `v1.1.0`: stable release 1.1.
120* 2019-09-01, `v1.0.8`: pre-release 8: more robust windows dynamic overriding, initial huge page support.
121* 2019-08-10, `v1.0.6`: pre-release 6: various performance improvements.
122
123Special thanks to:
124
125* [David Carlier](https://devnexen.blogspot.com/) (@devnexen) for his many contributions, and making
126  mimalloc work better on many less common operating systems, like Haiku, Dragonfly, etc.
127* Mary Feofanova (@mary3000), Evgeniy Moiseenko, and Manuel Pöter (@mpoeter) for making mimalloc TSAN checkable, and finding
128  memory model bugs using the [genMC] model checker.
129* Weipeng Liu (@pongba), Zhuowei Li, Junhua Wang, and Jakub Szymanski, for their early support of mimalloc and deployment
130  at large scale services, leading to many improvements in the mimalloc algorithms for large workloads.
131* Jason Gibson (@jasongibson) for exhaustive testing on large scale workloads and server environments, and finding complex bugs
132  in (early versions of) `mimalloc`.
133* Manuel Pöter (@mpoeter) and Sam Gross (@colesbury) for finding an ABA concurrency issue in abandoned segment reclamation.
134
135[genMC]: https://plv.mpi-sws.org/genmc/
136
137### Usage
138
139mimalloc is used in various large scale low-latency services and programs, for example:
140
141<a href="https://www.bing.com"><img align="left"  height="50" src="https://upload.wikimedia.org/wikipedia/commons/e/e9/Bing_logo.svg"></a>
142<a href="https://azure.microsoft.com/"><img align="left" height="50" src="https://upload.wikimedia.org/wikipedia/commons/a/a8/Microsoft_Azure_Logo.svg"></a>
143<a href="https://deathstrandingpc.505games.com"><img height="100" src="doc/ds-logo.jpg" style="border-radius=1ex;vertical-align:center"></a>
144
145# Building
146
147## Windows
148
149Open `ide/vs2019/mimalloc.sln` in Visual Studio 2019 and build.
150The `mimalloc` project builds a static library (in `out/msvc-x64`), while the
151`mimalloc-override` project builds a DLL for overriding malloc
152in the entire program.
153
154## macOS, Linux, BSD, etc.
155
156We use [`cmake`](https://cmake.org)<sup>1</sup> as the build system:
157
158```
159> mkdir -p out/release
160> cd out/release
161> cmake ../..
162> make
163```
164This builds the library as a shared (dynamic)
165library (`.so` or `.dylib`), a static library (`.a`), and
166as a single object file (`.o`).
167
168`> sudo make install` (install the library and header files in `/usr/local/lib`  and `/usr/local/include`)
169
170You can build the debug version which does many internal checks and
171maintains detailed statistics as:
172
173```
174> mkdir -p out/debug
175> cd out/debug
176> cmake -DCMAKE_BUILD_TYPE=Debug ../..
177> make
178```
179This will name the shared library as `libmimalloc-debug.so`.
180
181Finally, you can build a _secure_ version that uses guard pages, encrypted
182free lists, etc., as:
183```
184> mkdir -p out/secure
185> cd out/secure
186> cmake -DMI_SECURE=ON ../..
187> make
188```
189This will name the shared library as `libmimalloc-secure.so`.
190Use `ccmake`<sup>2</sup> instead of `cmake`
191to see and customize all the available build options.
192
193Notes:
1941. Install CMake: `sudo apt-get install cmake`
1952. Install CCMake: `sudo apt-get install cmake-curses-gui`
196
197
198## Single source
199
200You can also directly build the single `src/static.c` file as part of your project without
201needing `cmake` at all. Make sure to also add the mimalloc `include` directory to the include path.
202
203
204# Using the library
205
206The preferred usage is including `<mimalloc.h>`, linking with
207the shared- or static library, and using the `mi_malloc` API exclusively for allocation. For example,
208```
209> gcc -o myprogram -lmimalloc myfile.c
210```
211
212mimalloc uses only safe OS calls (`mmap` and `VirtualAlloc`) and can co-exist
213with other allocators linked to the same program.
214If you use `cmake`, you can simply use:
215```
216find_package(mimalloc 1.4 REQUIRED)
217```
218in your `CMakeLists.txt` to find a locally installed mimalloc. Then use either:
219```
220target_link_libraries(myapp PUBLIC mimalloc)
221```
222to link with the shared (dynamic) library, or:
223```
224target_link_libraries(myapp PUBLIC mimalloc-static)
225```
226to link with the static library. See `test\CMakeLists.txt` for an example.
227
228For best performance in C++ programs, it is also recommended to override the
229global `new` and `delete` operators. For convience, mimalloc provides
230[`mimalloc-new-delete.h`](https://github.com/microsoft/mimalloc/blob/master/include/mimalloc-new-delete.h) which does this for you -- just include it in a single(!) source file in your project.
231In C++, mimalloc also provides the `mi_stl_allocator` struct which implements the `std::allocator`
232interface.
233
234You can pass environment variables to print verbose messages (`MIMALLOC_VERBOSE=1`)
235and statistics (`MIMALLOC_SHOW_STATS=1`) (in the debug version):
236```
237> env MIMALLOC_SHOW_STATS=1 ./cfrac 175451865205073170563711388363
238
239175451865205073170563711388363 = 374456281610909315237213 * 468551
240
241heap stats:     peak      total      freed       unit
242normal   2:    16.4 kb    17.5 mb    17.5 mb      16 b   ok
243normal   3:    16.3 kb    15.2 mb    15.2 mb      24 b   ok
244normal   4:      64 b      4.6 kb     4.6 kb      32 b   ok
245normal   5:      80 b    118.4 kb   118.4 kb      40 b   ok
246normal   6:      48 b       48 b       48 b       48 b   ok
247normal  17:     960 b      960 b      960 b      320 b   ok
248
249heap stats:     peak      total      freed       unit
250    normal:    33.9 kb    32.8 mb    32.8 mb       1 b   ok
251      huge:       0 b        0 b        0 b        1 b   ok
252     total:    33.9 kb    32.8 mb    32.8 mb       1 b   ok
253malloc requested:         32.8 mb
254
255 committed:    58.2 kb    58.2 kb    58.2 kb       1 b   ok
256  reserved:     2.0 mb     2.0 mb     2.0 mb       1 b   ok
257     reset:       0 b        0 b        0 b        1 b   ok
258  segments:       1          1          1
259-abandoned:       0
260     pages:       6          6          6
261-abandoned:       0
262     mmaps:       3
263 mmap fast:       0
264 mmap slow:       1
265   threads:       0
266   elapsed:     2.022s
267   process: user: 1.781s, system: 0.016s, faults: 756, reclaims: 0, rss: 2.7 mb
268```
269
270The above model of using the `mi_` prefixed API is not always possible
271though in existing programs that already use the standard malloc interface,
272and another option is to override the standard malloc interface
273completely and redirect all calls to the _mimalloc_ library instead .
274
275## Environment Options
276
277You can set further options either programmatically (using [`mi_option_set`](https://microsoft.github.io/mimalloc/group__options.html)),
278or via environment variables:
279
280- `MIMALLOC_SHOW_STATS=1`: show statistics when the program terminates.
281- `MIMALLOC_VERBOSE=1`: show verbose messages.
282- `MIMALLOC_SHOW_ERRORS=1`: show error and warning messages.
283- `MIMALLOC_PAGE_RESET=0`: by default, mimalloc will reset (or purge) OS pages that are not in use, to signal to the OS
284   that the underlying physical memory can be reused. This can reduce memory fragmentation in long running (server)
285   programs. By setting it to `0` this will no longer be done which can improve performance for batch-like programs.
286   As an alternative, the `MIMALLOC_RESET_DELAY=`<msecs> can be set higher (100ms by default) to make the page
287   reset occur less frequently instead of turning it off completely.
288- `MIMALLOC_USE_NUMA_NODES=N`: pretend there are at most `N` NUMA nodes. If not set, the actual NUMA nodes are detected
289   at runtime. Setting `N` to 1 may avoid problems in some virtual environments. Also, setting it to a lower number than
290   the actual NUMA nodes is fine and will only cause threads to potentially allocate more memory across actual NUMA
291   nodes (but this can happen in any case as NUMA local allocation is always a best effort but not guaranteed).
292- `MIMALLOC_LARGE_OS_PAGES=1`: use large OS pages (2MiB) when available; for some workloads this can significantly
293   improve performance. Use `MIMALLOC_VERBOSE` to check if the large OS pages are enabled -- usually one needs
294   to explicitly allow large OS pages (as on [Windows][windows-huge] and [Linux][linux-huge]). However, sometimes
295   the OS is very slow to reserve contiguous physical memory for large OS pages so use with care on systems that
296   can have fragmented memory (for that reason, we generally recommend to use `MIMALLOC_RESERVE_HUGE_OS_PAGES` instead whenever possible).
297   <!--
298   - `MIMALLOC_EAGER_REGION_COMMIT=1`: on Windows, commit large (256MiB) regions eagerly. On Windows, these regions
299   show in the working set even though usually just a small part is committed to physical memory. This is why it
300   turned off by default on Windows as it looks not good in the task manager. However, turning it on has no
301   real drawbacks and may improve performance by a little.
302   -->
303- `MIMALLOC_RESERVE_HUGE_OS_PAGES=N`: where N is the number of 1GiB _huge_ OS pages. This reserves the huge pages at
304   startup and sometimes this can give a large (latency) performance improvement on big workloads.
305   Usually it is better to not use
306   `MIMALLOC_LARGE_OS_PAGES` in combination with this setting. Just like large OS pages, use with care as reserving
307   contiguous physical memory can take a long time when memory is fragmented (but reserving the huge pages is done at
308   startup only once).
309   Note that we usually need to explicitly enable huge OS pages (as on [Windows][windows-huge] and [Linux][linux-huge])).
310   With huge OS pages, it may be beneficial to set the setting
311   `MIMALLOC_EAGER_COMMIT_DELAY=N` (`N` is 1 by default) to delay the initial `N` segments (of 4MiB)
312   of a thread to not allocate in the huge OS pages; this prevents threads that are short lived
313   and allocate just a little to take up space in the huge OS page area (which cannot be reset).
314   The huge pages are usually allocated evenly among NUMA nodes.
315   We can use `MIMALLOC_RESERVE_HUGE_OS_PAGES_AT=N` where `N` is the numa node (starting at 0) to allocate all
316   the huge pages at a specific numa node instead.
317
318Use caution when using `fork` in combination with either large or huge OS pages: on a fork, the OS uses copy-on-write
319for all pages in the original process including the huge OS pages. When any memory is now written in that area, the
320OS will copy the entire 1GiB huge page (or 2MiB large page) which can cause the memory usage to grow in big increments.
321
322[linux-huge]: https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/5/html/tuning_and_optimizing_red_hat_enterprise_linux_for_oracle_9i_and_10g_databases/sect-oracle_9i_and_10g_tuning_guide-large_memory_optimization_big_pages_and_huge_pages-configuring_huge_pages_in_red_hat_enterprise_linux_4_or_5
323[windows-huge]: https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/enable-the-lock-pages-in-memory-option-windows?view=sql-server-2017
324
325## Secure Mode
326
327_mimalloc_ can be build in secure mode by using the `-DMI_SECURE=ON` flags in `cmake`. This build enables various mitigations
328to make mimalloc more robust against exploits. In particular:
329
330- All internal mimalloc pages are surrounded by guard pages and the heap metadata is behind a guard page as well (so a buffer overflow
331  exploit cannot reach into the metadata).
332- All free list pointers are
333  [encoded](https://github.com/microsoft/mimalloc/blob/783e3377f79ee82af43a0793910a9f2d01ac7863/include/mimalloc-internal.h#L396)
334  with per-page keys which is used both to prevent overwrites with a known pointer, as well as to detect heap corruption.
335- Double free's are detected (and ignored).
336- The free lists are initialized in a random order and allocation randomly chooses between extension and reuse within a page to
337  mitigate against attacks that rely on a predicable allocation order. Similarly, the larger heap blocks allocated by mimalloc
338  from the OS are also address randomized.
339
340As always, evaluate with care as part of an overall security strategy as all of the above are mitigations but not guarantees.
341
342## Debug Mode
343
344When _mimalloc_ is built using debug mode, various checks are done at runtime to catch development errors.
345
346- Statistics are maintained in detail for each object size. They can be shown using `MIMALLOC_SHOW_STATS=1` at runtime.
347- All objects have padding at the end to detect (byte precise) heap block overflows.
348- Double free's, and freeing invalid heap pointers are detected.
349- Corrupted free-lists and some forms of use-after-free are detected.
350
351
352# Overriding Standard Malloc
353
354Overriding the standard `malloc` (and `new`) can be done either _dynamically_ or _statically_.
355
356## Dynamic override
357
358This is the recommended way to override the standard malloc interface.
359
360### Override on Linux, BSD
361
362On these ELF-based systems we preload the mimalloc shared
363library so all calls to the standard `malloc` interface are
364resolved to the _mimalloc_ library.
365```
366> env LD_PRELOAD=/usr/lib/libmimalloc.so myprogram
367```
368
369You can set extra environment variables to check that mimalloc is running,
370like:
371```
372> env MIMALLOC_VERBOSE=1 LD_PRELOAD=/usr/lib/libmimalloc.so myprogram
373```
374or run with the debug version to get detailed statistics:
375```
376> env MIMALLOC_SHOW_STATS=1 LD_PRELOAD=/usr/lib/libmimalloc-debug.so myprogram
377```
378
379### Override on MacOS
380
381On macOS we can also preload the mimalloc shared
382library so all calls to the standard `malloc` interface are
383resolved to the _mimalloc_ library.
384```
385> env DYLD_INSERT_LIBRARIES=/usr/lib/libmimalloc.dylib myprogram
386```
387
388Note that certain security restrictions may apply when doing this from
389the [shell](https://stackoverflow.com/questions/43941322/dyld-insert-libraries-ignored-when-calling-application-through-bash).
390
391
392### Override on Windows
393
394<span id="override_on_windows">Overriding on Windows</span> is robust and has the
395particular advantage to be able to redirect all malloc/free calls that go through
396the (dynamic) C runtime allocator, including those from other DLL's or libraries.
397
398The overriding on Windows requires that you link your program explicitly with
399the mimalloc DLL and use the C-runtime library as a DLL (using the `/MD` or `/MDd` switch).
400Also, the `mimalloc-redirect.dll` (or `mimalloc-redirect32.dll`) must be put
401in the same folder as the main `mimalloc-override.dll` at runtime (as it is a dependency).
402The redirection DLL ensures that all calls to the C runtime malloc API get redirected to
403mimalloc (in `mimalloc-override.dll`).
404
405To ensure the mimalloc DLL is loaded at run-time it is easiest to insert some
406call to the mimalloc API in the `main` function, like `mi_version()`
407(or use the `/INCLUDE:mi_version` switch on the linker). See the `mimalloc-override-test` project
408for an example on how to use this. For best performance on Windows with C++, it
409is also recommended to also override the `new`/`delete` operations (by including
410[`mimalloc-new-delete.h`](https://github.com/microsoft/mimalloc/blob/master/include/mimalloc-new-delete.h) a single(!) source file in your project).
411
412The environment variable `MIMALLOC_DISABLE_REDIRECT=1` can be used to disable dynamic
413overriding at run-time. Use `MIMALLOC_VERBOSE=1` to check if mimalloc was successfully redirected.
414
415(Note: in principle, it is possible to even patch existing executables without any recompilation
416if they are linked with the dynamic C runtime (`ucrtbase.dll`) -- just put the `mimalloc-override.dll`
417into the import table (and put `mimalloc-redirect.dll` in the same folder)
418Such patching can be done for example with [CFF Explorer](https://ntcore.com/?page_id=388)).
419
420
421## Static override
422
423On Unix-like systems, you can also statically link with _mimalloc_ to override the standard
424malloc interface. The recommended way is to link the final program with the
425_mimalloc_ single object file (`mimalloc-override.o`). We use
426an object file instead of a library file as linkers give preference to
427that over archives to resolve symbols. To ensure that the standard
428malloc interface resolves to the _mimalloc_ library, link it as the first
429object file. For example:
430```
431> gcc -o myprogram mimalloc-override.o  myfile1.c ...
432```
433
434Another way to override statically that works on all platforms, is to
435link statically to mimalloc (as shown in the introduction) and include a
436header file in each source file that re-defines `malloc` etc. to `mi_malloc`.
437This is provided by [`mimalloc-override.h`](https://github.com/microsoft/mimalloc/blob/master/include/mimalloc-override.h). This only works reliably though if all sources are
438under your control or otherwise mixing of pointers from different heaps may occur!
439
440
441# Performance
442
443Last update: 2021-01-30
444
445We tested _mimalloc_ against many other top allocators over a wide
446range of benchmarks, ranging from various real world programs to
447synthetic benchmarks that see how the allocator behaves under more
448extreme circumstances. In our benchmark suite, _mimalloc_ outperforms other leading
449allocators (_jemalloc_, _tcmalloc_, _Hoard_, etc), and has a similar memory footprint. A nice property is that it
450does consistently well over the wide range of benchmarks.
451
452General memory allocators are interesting as there exists no algorithm that is
453optimal -- for a given allocator one can usually construct a workload
454where it does not do so well. The goal is thus to find an allocation
455strategy that performs well over a wide range of benchmarks without
456suffering from (too much) underperformance in less common situations.
457
458As always, interpret these results with care since some benchmarks test synthetic
459or uncommon situations that may never apply to your workloads. For example, most
460allocators do not do well on `xmalloc-testN` but that includes even the best
461industrial allocators like _jemalloc_ and _tcmalloc_ that are used in some of
462the world's largest systems (like Chrome or FreeBSD).
463
464Also, the benchmarks here do not measure the behaviour on very large and long-running server workloads,
465or worst-case latencies of allocation. Much work has gone into `mimalloc` to work well on such
466workloads (for example, to reduce virtual memory fragmentation on long-running services)
467but such optimizations are not always reflected in the current benchmark suite.
468
469We show here only an overview -- for
470more specific details and further benchmarks we refer to the
471[technical report](https://www.microsoft.com/en-us/research/publication/mimalloc-free-list-sharding-in-action).
472The benchmark suite is automated and available separately
473as [mimalloc-bench](https://github.com/daanx/mimalloc-bench).
474
475
476## Benchmark Results on a 16-core AMD 5950x (Zen3)
477
478Testing on the 16-core AMD 5950x processor at 3.4Ghz (4.9Ghz boost), with
479with 32GiB memory at 3600Mhz, running	Ubuntu 20.04 with glibc 2.31 and GCC 9.3.0.
480
481We measure three versions of _mimalloc_: the main version `mi` (tag:v1.7.0),
482the new v2.0 beta version as `xmi` (tag:v2.0.0), and the main version in secure mode as `smi` (tag:v1.7.0).
483
484The other allocators are
485Google's [_tcmalloc_](https://github.com/gperftools/gperftools) (`tc`, tag:gperftools-2.8.1) used in Chrome,
486Facebook's [_jemalloc_](https://github.com/jemalloc/jemalloc) (`je`, tag:5.2.1) by Jason Evans used in Firefox and FreeBSD,
487the Intel thread building blocks [allocator](https://github.com/intel/tbb) (`tbb`, tag:v2020.3),
488[rpmalloc](https://github.com/mjansson/rpmalloc) (`rp`,tag:1.4.1) by Mattias Jansson,
489the original scalable [_Hoard_](https://github.com/emeryberger/Hoard) (git:d880f72) allocator by Emery Berger \[1],
490the memory compacting [_Mesh_](https://github.com/plasma-umass/Mesh) (git:67ff31a) allocator by
491Bobby Powers _et al_ \[8],
492and finally the default system allocator (`glibc`, 2.31) (based on _PtMalloc2_).
493
494<img width="90%" src="doc/bench-2021/bench-amd5950x-2021-01-30-a.svg"/>
495<img width="90%" src="doc/bench-2021/bench-amd5950x-2021-01-30-b.svg"/>
496
497Any benchmarks ending in `N` run on all 32 logical cores in parallel.
498Results are averaged over 10 runs and reported relative
499to mimalloc (where 1.2 means it took 1.2&times; longer to run).
500The legend also contains the _overall relative score_ between the
501allocators where 100 points is the maximum if an allocator is fastest on
502all benchmarks.
503
504The single threaded _cfrac_ benchmark by Dave Barrett is an implementation of
505continued fraction factorization which uses many small short-lived allocations.
506All allocators do well on such common usage, where _mimalloc_ is just a tad
507faster than _tcmalloc_ and
508_jemalloc_.
509
510The _leanN_ program is interesting as a large realistic and
511concurrent workload of the [Lean](https://github.com/leanprover/lean)
512theorem prover compiling its own standard library, and there is a 13%
513speedup over _tcmalloc_. This is
514quite significant: if Lean spends 20% of its time in the
515allocator that means that _mimalloc_ is 1.6&times; faster than _tcmalloc_
516here. (This is surprising as that is not measured in a pure
517allocation benchmark like _alloc-test_. We conjecture that we see this
518outsized improvement here because _mimalloc_ has better locality in
519the allocation which improves performance for the *other* computations
520in a program as well).
521
522The single threaded _redis_ benchmark again show that most allocators do well on such workloads.
523
524The _larsonN_ server benchmark by Larson and Krishnan \[2] allocates and frees between threads. They observed this
525behavior (which they call _bleeding_) in actual server applications, and the benchmark simulates this.
526Here, _mimalloc_ is quite a bit faster than _tcmalloc_ and _jemalloc_ probably due to the object migration between different threads.
527
528The _mstressN_ workload performs many allocations and re-allocations,
529and migrates objects between threads (as in _larsonN_). However, it also
530creates  and destroys the _N_ worker threads a few times keeping some objects
531alive beyond the life time of the allocating thread. We observed this
532behavior in many larger server applications.
533
534The [_rptestN_](https://github.com/mjansson/rpmalloc-benchmark) benchmark
535by Mattias Jansson is a allocator test originally designed
536for _rpmalloc_, and tries to simulate realistic allocation patterns over
537multiple threads. Here the differences between allocators become more apparent.
538
539The second benchmark set tests specific aspects of the allocators and
540shows even more extreme differences between them.
541
542The _alloc-test_, by
543[OLogN Technologies AG](http://ithare.com/testing-memory-allocators-ptmalloc2-tcmalloc-hoard-jemalloc-while-trying-to-simulate-real-world-loads/), is a very allocation intensive benchmark doing millions of
544allocations in various size classes. The test is scaled such that when an
545allocator performs almost identically on _alloc-test1_ as _alloc-testN_ it
546means that it scales linearly.
547
548The _sh6bench_ and _sh8bench_ benchmarks are
549developed by [MicroQuill](http://www.microquill.com/) as part of SmartHeap.
550In _sh6bench_ _mimalloc_ does much
551better than the others (more than 2.5&times; faster than _jemalloc_).
552We cannot explain this well but believe it is
553caused in part by the "reverse" free-ing pattern in _sh6bench_.
554The _sh8bench_ is a variation with object migration
555between threads; whereas _tcmalloc_ did well on _sh6bench_, the addition of object migration causes it to be 10&times; slower than before.
556
557The _xmalloc-testN_ benchmark by Lever and Boreham \[5] and Christian Eder, simulates an asymmetric workload where
558some threads only allocate, and others only free -- they observed this pattern in
559larger server applications. Here we see that
560the _mimalloc_ technique of having non-contended sharded thread free
561lists pays off as it outperforms others by a very large margin. Only _rpmalloc_, _tbb_, and _glibc_ also scale well on this benchmark.
562
563The _cache-scratch_ benchmark by Emery Berger \[1], and introduced with
564the Hoard allocator to test for _passive-false_ sharing of cache lines.
565With a single thread they all
566perform the same, but when running with multiple threads the potential allocator
567induced false sharing of the cache lines can cause large run-time differences.
568Crundal \[6] describes in detail why the false cache line sharing occurs in the _tcmalloc_ design, and also discusses how this
569can be avoided with some small implementation changes.
570Only the _tbb_, _rpmalloc_ and _mesh_ allocators also avoid the
571cache line sharing completely, while _Hoard_ and _glibc_ seem to mitigate
572the effects. Kukanov and Voss \[7] describe in detail
573how the design of _tbb_ avoids the false cache line sharing.
574
575
576## On a 36-core Intel Xeon
577
578For completeness, here are the results on a big Amazon
579[c5.18xlarge](https://aws.amazon.com/ec2/instance-types/#Compute_Optimized) instance
580consisting of a 2&times;18-core Intel Xeon (Cascade Lake) at 3.4GHz (boost 3.5GHz)
581with 144GiB ECC memory, running	Ubuntu 20.04 with glibc 2.31, GCC 9.3.0, and
582Clang 10.0.0. This time, the mimalloc allocators (mi, xmi, and smi) were
583compiled with the Clang compiler instead of GCC.
584The results are similar to the AMD results but it is interesting to
585see the differences in the _larsonN_, _mstressN_, and _xmalloc-testN_ benchmarks.
586
587<img width="90%" src="doc/bench-2021/bench-c5-18xlarge-2021-01-30-a.svg"/>
588<img width="90%" src="doc/bench-2021/bench-c5-18xlarge-2021-01-30-b.svg"/>
589
590
591## Peak Working Set
592
593The following figure shows the peak working set (rss) of the allocators
594on the benchmarks (on the c5.18xlarge instance).
595
596<img width="90%" src="doc/bench-2021/bench-c5-18xlarge-2021-01-30-rss-a.svg"/>
597<img width="90%" src="doc/bench-2021/bench-c5-18xlarge-2021-01-30-rss-b.svg"/>
598
599Note that the _xmalloc-testN_ memory usage should be disregarded as it
600allocates more the faster the program runs. Similarly, memory usage of
601_larsonN_, _mstressN_, _rptestN_ and _sh8bench_ can vary depending on scheduling and
602speed. Nevertheless, we hope to improve the memory usage on _mstressN_
603and _rptestN_ (just as _cfrac_, _larsonN_ and _sh8bench_ have a small working set which skews the results).
604
605<!--
606# Previous Benchmarks
607
608Todo: should we create a separate page for this?
609
610## Benchmark Results on 36-core Intel: 2020-01-20
611
612Testing on a big Amazon EC2 compute instance
613([c5.18xlarge](https://aws.amazon.com/ec2/instance-types/#Compute_Optimized))
614consisting of a 72 processor Intel Xeon at 3GHz
615with 144GiB ECC memory, running	Ubuntu 18.04.1 with glibc 2.27 and GCC 7.4.0.
616The measured allocators are _mimalloc_ (xmi, tag:v1.4.0, page reset enabled)
617and its secure build as _smi_,
618Google's [_tcmalloc_](https://github.com/gperftools/gperftools) (tc, tag:gperftools-2.7) used in Chrome,
619Facebook's [_jemalloc_](https://github.com/jemalloc/jemalloc) (je, tag:5.2.1) by Jason Evans used in Firefox and FreeBSD,
620the Intel thread building blocks [allocator](https://github.com/intel/tbb) (tbb, tag:2020),
621[rpmalloc](https://github.com/mjansson/rpmalloc) (rp,tag:1.4.0) by Mattias Jansson,
622the original scalable [_Hoard_](https://github.com/emeryberger/Hoard) (tag:3.13) allocator by Emery Berger \[1],
623the memory compacting [_Mesh_](https://github.com/plasma-umass/Mesh) (git:51222e7) allocator by
624Bobby Powers _et al_ \[8],
625and finally the default system allocator (glibc, 2.27) (based on _PtMalloc2_).
626
627<img width="90%" src="doc/bench-2020/bench-c5-18xlarge-2020-01-20-a.svg"/>
628<img width="90%" src="doc/bench-2020/bench-c5-18xlarge-2020-01-20-b.svg"/>
629
630The following figure shows the peak working set (rss) of the allocators
631on the benchmarks (on the c5.18xlarge instance).
632
633<img width="90%" src="doc/bench-2020/bench-c5-18xlarge-2020-01-20-rss-a.svg"/>
634<img width="90%" src="doc/bench-2020/bench-c5-18xlarge-2020-01-20-rss-b.svg"/>
635
636
637## On 24-core AMD Epyc, 2020-01-16
638
639For completeness, here are the results on a
640[r5a.12xlarge](https://aws.amazon.com/ec2/instance-types/#Memory_Optimized) instance
641having a 48 processor AMD Epyc 7000 at 2.5GHz with 384GiB of memory.
642The results are similar to the Intel results but it is interesting to
643see the differences in the _larsonN_, _mstressN_, and _xmalloc-testN_ benchmarks.
644
645<img width="90%" src="doc/bench-2020/bench-r5a-12xlarge-2020-01-16-a.svg"/>
646<img width="90%" src="doc/bench-2020/bench-r5a-12xlarge-2020-01-16-b.svg"/>
647
648-->
649
650# References
651
652- \[1] Emery D. Berger, Kathryn S. McKinley, Robert D. Blumofe, and Paul R. Wilson.
653   _Hoard: A Scalable Memory Allocator for Multithreaded Applications_
654   the Ninth International Conference on Architectural Support for Programming Languages and Operating Systems (ASPLOS-IX). Cambridge, MA, November 2000.
655   [pdf](http://www.cs.utexas.edu/users/mckinley/papers/asplos-2000.pdf)
656
657- \[2] P. Larson and M. Krishnan. _Memory allocation for long-running server applications_.
658  In ISMM, Vancouver, B.C., Canada, 1998. [pdf](http://citeseer.ist.psu.edu/viewdoc/download?doi=10.1.1.45.1947&rep=rep1&type=pdf)
659
660- \[3] D. Grunwald, B. Zorn, and R. Henderson.
661  _Improving the cache locality of memory allocation_. In R. Cartwright, editor,
662  Proceedings of the Conference on Programming Language Design and Implementation, pages 177–186, New York, NY, USA, June 1993. [pdf](http://citeseer.ist.psu.edu/viewdoc/download?doi=10.1.1.43.6621&rep=rep1&type=pdf)
663
664- \[4] J. Barnes and P. Hut. _A hierarchical O(n*log(n)) force-calculation algorithm_. Nature, 324:446-449, 1986.
665
666- \[5] C. Lever, and D. Boreham. _Malloc() Performance in a Multithreaded Linux Environment._
667  In USENIX Annual Technical Conference, Freenix Session. San Diego, CA. Jun. 2000.
668  Available at <https://github.com/kuszmaul/SuperMalloc/tree/master/tests>
669
670- \[6] Timothy Crundal. _Reducing Active-False Sharing in TCMalloc_. 2016. CS16S1 project at the Australian National University. [pdf](http://courses.cecs.anu.edu.au/courses/CSPROJECTS/16S1/Reports/Timothy_Crundal_Report.pdf)
671
672- \[7] Alexey Kukanov, and Michael J Voss.
673   _The Foundations for Scalable Multi-Core Software in Intel Threading Building Blocks._
674   Intel Technology Journal 11 (4). 2007
675
676- \[8] Bobby Powers, David Tench, Emery D. Berger, and Andrew McGregor.
677 _Mesh: Compacting Memory Management for C/C++_
678 In Proceedings of the 40th ACM SIGPLAN Conference on Programming Language Design and Implementation (PLDI'19), June 2019, pages 333-–346.
679
680<!--
681- \[9] Paul Liétar, Theodore Butler, Sylvan Clebsch, Sophia Drossopoulou, Juliana Franco, Matthew J Parkinson,
682  Alex Shamis, Christoph M Wintersteiger, and David Chisnall.
683  _Snmalloc: A Message Passing Allocator._
684  In Proceedings of the 2019 ACM SIGPLAN International Symposium on Memory Management, 122–135. ACM. 2019.
685-->
686
687
688# Contributing
689
690This project welcomes contributions and suggestions.  Most contributions require you to agree to a
691Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
692the rights to use your contribution. For details, visit https://cla.microsoft.com.
693
694When you submit a pull request, a CLA-bot will automatically determine whether you need to provide
695a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions
696provided by the bot. You will only need to do this once across all repos using our CLA.
697