diff options
author | daan <daanl@outlook.com> | 2019-09-11 20:48:41 -0700 |
---|---|---|
committer | daan <daanl@outlook.com> | 2019-09-11 20:48:41 -0700 |
commit | c977a1629d52557e46a0b43985144f267f758c90 (patch) | |
tree | 9861421a3ab155030c3a021edb48d3b0ac1bd4b6 /doc/mimalloc-doc.h | |
parent | 24777f6a9116d51a1ba6f79e619bedeef3b4d06f (diff) |
update documentation
Diffstat (limited to 'doc/mimalloc-doc.h')
-rw-r--r-- | doc/mimalloc-doc.h | 150 |
1 files changed, 122 insertions, 28 deletions
diff --git a/doc/mimalloc-doc.h b/doc/mimalloc-doc.h index e4f8590..5ad5a1e 100644 --- a/doc/mimalloc-doc.h +++ b/doc/mimalloc-doc.h @@ -48,20 +48,23 @@ Notable aspects of the design include: - __first-class heaps__: efficiently create and use multiple heaps to allocate across different regions. A heap can be destroyed at once instead of deallocating each object separately. - __bounded__: it does not suffer from _blowup_ \[1\], has bounded worst-case allocation - times (_wcat_), bounded space overhead (~0.2% meta-data, with at most 16.7% waste in allocation sizes), + times (_wcat_), bounded space overhead (~0.2% meta-data, with at most 12.5% waste in allocation sizes), and has no internal points of contention using only atomic operations. - __fast__: In our benchmarks (see [below](#performance)), _mimalloc_ always outperforms all other leading allocators (_jemalloc_, _tcmalloc_, _Hoard_, etc), and usually uses less memory (up to 25% more in the worst case). A nice property is that it does consistently well over a wide range of benchmarks. -You can read more on the design of _mimalloc_ in the upcoming technical report +You 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. + Further information: - \ref build - \ref using +- \ref environment - \ref overrides - \ref bench - \ref malloc @@ -293,31 +296,34 @@ size_t mi_good_size(size_t size); /// resource usage by calling this every once in a while. void mi_collect(bool force); -/// Print statistics. -/// @param out Output file. Use \a NULL for \a stderr. +/// Print the main statistics. +/// @param out Output function. Use \a NULL for outputting to \a stderr. /// /// Most detailed when using a debug build. -void mi_stats_print(FILE* out); +void mi_stats_print(mi_output_fun* out); /// Reset statistics. -void mi_stats_reset(); +void mi_stats_reset(void); + +/// Merge thread local statistics with the main statistics and reset. +void mi_stats_merge(void); /// Initialize mimalloc on a thread. /// Should not be used as on most systems (pthreads, windows) this is done /// automatically. -void mi_thread_init(); +void mi_thread_init(void); /// Uninitialize mimalloc on a thread. /// Should not be used as on most systems (pthreads, windows) this is done /// automatically. Ensures that any memory that is not freed yet (but will /// be freed by other threads in the future) is properly handled. -void mi_thread_done(); +void mi_thread_done(void); /// Print out heap statistics for this thread. -/// @param out Output file. Use \a NULL for \a stderr. +/// @param out Output function. Use \a NULL for outputting to \a stderr. /// /// Most detailed when using a debug build. -void mi_thread_stats_print(FILE* out); +void mi_thread_stats_print(mi_output_fun* out); /// Type of deferred free functions. /// @param force If \a true all outstanding items should be freed. @@ -342,6 +348,45 @@ typedef void (mi_deferred_free_fun)(bool force, unsigned long long heartbeat); /// At most one \a deferred_free function can be active. void mi_register_deferred_free(mi_deferred_free_fun* deferred_free); +/// Type of output functions. +/// @param msg Message to output. +/// +/// @see mi_register_output() +typedef void (mi_output_fun)(const char* msg); + +/// Register an output function. +/// @param out The output function, use `NULL` to output to stdout. +/// +/// The `out` function is called to output any information from mimalloc, +/// like verbose or warning messages. +void mi_register_output(mi_output_fun* out) mi_attr_noexcept; + +/// Is a pointer part of our heap? +/// @param p The pointer to check. +/// @returns \a true if this is a pointer into our heap. +/// This function is relatively fast. +bool mi_is_in_heap_region(const void* p); + +/// Reserve \a pages of huge OS pages (1GiB) but stops after at most `max_secs` seconds. +/// @param pages The number of 1GiB pages to reserve. +/// @param max_secs Maximum number of seconds to try reserving. +/// @param pages_reserved If not \a NULL, it is set to the actual number of pages that were reserved. +/// @returns 0 if successfull, \a ENOMEM if running out of memory, or \a ETIMEDOUT if timed out. +/// +/// The reserved memory is used by mimalloc to satisfy allocations. +/// May quit before \a max_secs are expired if it estimates it will take more than +/// 1.5 times \a max_secs. The time limit is needed because on some operating systems +/// it can take a long time to reserve contiguous memory if the physical memory is +/// fragmented. +int mi_reserve_huge_os_pages(size_t pages, double max_secs, size_t* pages_reserved); + +/// Is the C runtime \a malloc API redirected? +/// @returns \a true if all malloc API calls are redirected to mimalloc. +/// +/// Currenty only used on Windows. +bool mi_is_redirected(); + + /// \} // ------------------------------------------------------ @@ -443,10 +488,18 @@ mi_heap_t* mi_heap_get_default(); /// except by exiting the thread. mi_heap_t* mi_heap_get_backing(); +/// Release outstanding resources in a specific heap. +void mi_heap_collect(mi_heap_t* heap, bool force); + /// Allocate in a specific heap. /// @see mi_malloc() void* mi_heap_malloc(mi_heap_t* heap, size_t size); +/// Allocate a small object in a specific heap. +/// \a size must be smaller or equal to MI_SMALL_SIZE_MAX(). +/// @see mi_malloc() +void* mi_heap_malloc_small(mi_heap_t* heap, size_t size); + /// Allocate zero-initialized in a specific heap. /// @see mi_zalloc() void* mi_heap_zalloc(mi_heap_t* heap, size_t size); @@ -486,6 +539,34 @@ void* mi_heap_realloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_ /// \} + +/// \defgroup zeroinit Zero initialized re-allocation +/// +/// The zero-initialized re-allocations are only valid on memory that was +/// originally allocated with zero initialization too. +/// e.g. `mi_calloc`, `mi_zalloc`, `mi_zalloc_aligned` etc. +/// see <https://github.com/microsoft/mimalloc/issues/63#issuecomment-508272992> +/// +/// \{ + +void* mi_rezalloc(void* p, size_t newsize); +void* mi_recalloc(void* p, size_t newcount, size_t size) ; + +void* mi_rezalloc_aligned(void* p, size_t newsize, size_t alignment); +void* mi_rezalloc_aligned_at(void* p, size_t newsize, size_t alignment, size_t offset); +void* mi_recalloc_aligned(void* p, size_t newcount, size_t size, size_t alignment); +void* mi_recalloc_aligned_at(void* p, size_t newcount, size_t size, size_t alignment, size_t offset); + +void* mi_heap_rezalloc(mi_heap_t* heap, void* p, size_t newsize); +void* mi_heap_recalloc(mi_heap_t* heap, void* p, size_t newcount, size_t size); + +void* mi_heap_rezalloc_aligned(mi_heap_t* heap, void* p, size_t newsize, size_t alignment); +void* mi_heap_rezalloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_t alignment, size_t offset); +void* mi_heap_recalloc_aligned(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment); +void* mi_heap_recalloc_aligned_at(mi_heap_t* heap, void* p, size_t newcount, size_t size, size_t alignment, size_t offset); + +/// \} + /// \defgroup typed Typed Macros /// /// Typed allocation macros @@ -532,6 +613,9 @@ void* mi_heap_realloc_aligned_at(mi_heap_t* heap, void* p, size_t newsize, size_ /// Re-allocate to \a count blocks of type \a tp in a heap \a hp. #define mi_heap_reallocn_tp(hp,p,tp,count) ((tp*)mi_heap_reallocn(p,count,sizeof(tp))) +/// Re-allocate to \a count zero initialized blocks of type \a tp in a heap \a hp. +#define mi_heap_recalloc_tp(hp,p,tp,count) ((tp*)mi_heap_recalloc(p,count,sizeof(tp))) + /// \} /// \defgroup analysis Heap Introspection @@ -614,14 +698,17 @@ typedef enum mi_option_e { mi_option_show_errors, ///< Print error messages to `stderr`. mi_option_verbose, ///< Print verbose messages to `stderr`. // the following options are experimental - mi_option_secure, ///< Experimental mi_option_eager_commit, ///< Eagerly commit segments (4MiB) (enabled by default). - mi_option_eager_region_commit, ///< Eagerly commit large (256MiB) memory regions (enabled by default except on Windows) - mi_option_large_os_pages, ///< Use large OS pages if possible + mi_option_eager_region_commit, ///< Eagerly commit large (256MiB) memory regions (enabled by default, except on Windows) + mi_option_large_os_pages, ///< Use large OS pages (2MiB in size) if possible + mi_option_reserve_huge_os_pages, ///< The number of huge OS pages (1GiB in size) to reserve at the start of the program. + mi_option_segment_cache, ///< The number of segments per thread to keep cached. mi_option_page_reset, ///< Reset page memory when it becomes free. mi_option_cache_reset, ///< Reset segment memory when a segment is cached. mi_option_reset_decommits, ///< Experimental - mi_option_reset_discards, ///< Experimental + mi_option_eager_commit_delay, ///< Experimental + mi_option_segment_reset, ///< Experimental + mi_option_os_tag, ///< OS tag to assign to mimalloc'd memory _mi_option_last } mi_option_t; @@ -647,6 +734,8 @@ void mi_option_set_default(mi_option_t option, long value); void* mi_recalloc(void* p, size_t count, size_t size); size_t mi_malloc_size(const void* p); size_t mi_malloc_usable_size(const void *p); + +/// Just as `free` but also checks if the pointer `p` belongs to our heap. void mi_cfree(void* p); int mi_posix_memalign(void** p, size_t alignment, size_t size); @@ -804,9 +893,12 @@ completely and redirect all calls to the _mimalloc_ library instead. See \ref overrides for more info. -## Environment Options +*/ + +/*! \page environment Environment Options -You can set further options either programmatically (using [`mi_option_set`](https://microsoft.github.io/mimalloc/group__options.html)), +You can set further options either programmatically +(using [`mi_option_set`](https://microsoft.github.io/mimalloc/group__options.html)), or via environment variables. - `MIMALLOC_SHOW_STATS=1`: show statistics when the program terminates. @@ -869,19 +961,23 @@ Note: unfortunately, at this time, dynamic overriding on macOS seems broken but ### Windows On Windows you need to link your program explicitly with the mimalloc -DLL, and use the C-runtime library as a DLL (the `/MD` or `/MDd` switch). -To ensure the mimalloc DLL gets loaded it is easiest to insert some +DLL and use the C-runtime library as a DLL (using the `/MD` or `/MDd` switch). +Moreover, you need to ensure the `mimalloc-redirect.dll` (or `mimalloc-redirect32.dll`) is available +in the same folder as the mimalloc DLL at runtime (as it as referred to by the mimalloc DLL). +The redirection DLL's ensure all calls to the C runtime malloc API get redirected to mimalloc. + +To ensure the mimalloc DLL is loaded at run-time it is easiest to insert some call to the mimalloc API in the `main` function, like `mi_version()` -(or use the `/INCLUDE:mi_version` switch on the linker) +(or use the `/INCLUDE:mi_version` switch on the linker). See the `mimalloc-override-test` project +for an example on how to use this. -Due to the way mimalloc intercepts the standard malloc at runtime, it is best -to link to the mimalloc import library first on the command line so it gets -loaded right after the universal C runtime DLL (`ucrtbase`). See -the `mimalloc-override-test` project for an example. +The environment variable `MIMALLOC_DISABLE_REDIRECT=1` can be used to disable dynamic +overriding at run-time. Use `MIMALLOC_VERBOSE=1` to check if mimalloc successfully redirected. -Note: the current overriding on Windows works for most programs but some programs still have -trouble -- the `dev-exp` branch contains a newer way of overriding that is more -robust; try this out if you experience troubles. +(Note: in principle, it should be possible to patch existing executables +that are linked with the dynamic C runtime (`ucrtbase.dll`) by just putting the mimalloc DLL into +the import table (and putting `mimalloc-redirect.dll` in the same folder) +Such patching can be done for example with [CFF Explorer](https://ntcore.com/?page_id=388)). ## Static override @@ -897,8 +993,6 @@ object file. For example: gcc -o myprogram mimalloc-override.o myfile1.c ... ``` - - ## List of Overrides: The specific functions that get redirected to the _mimalloc_ library are: |