build: use mimalloc
mimalloc is a compact general purpose allocator from Microsoft. It consistently outperforms glibc's `malloc()` in allocation-heavy workloads, such as Lix's evaluator It's currently only linked in the main `nix` executable, as Boehm's GC uses its own allocator. Other allocations that *do* go through glibc's `malloc()` are still much faster, though Benchmarked on x86_64-linux against Nixpkgs `bd07873`: | attribute | thunks | lix@`1396012` | mimalloc | uplift | |-------------------|---------|---------------|----------|--------| | hello | 206444 | 0.726s | 0.620s | 1.17x | | chromium | 1177382 | 2.273s | 2.136s | 1.06x | | firefox-unwrapped | 1394797 | 2.521s | 2.378s | 1.06x | | texliveFull | 3186440 | 4.992s | 4.672s | 1.07x | | nixosTests.gnome | 7905808 | 6.115s | 5.723s | 1.07x | Based-on: https://github.com/NixOS/nix/pull/15596 Co-authored-by: Bernardo Meurer Costa <beme@anthropic.com> Change-Id: I3ad92eacc075efeaf3d9f7730ada7b29835536a4
This commit is contained in:
committed by
seth
co-authored by
Bernardo Meurer Costa
parent
12f10fca7e
commit
c1370bc81c
@@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
synopsis: "Use mimalloc for faster evaluation"
|
||||||
|
cls: [5645]
|
||||||
|
category: Features
|
||||||
|
credits: [getchoo, lovesegfault]
|
||||||
|
---
|
||||||
|
|
||||||
|
Lix now links with [mimalloc](https://github.com/microsoft/mimalloc),
|
||||||
|
replacing the system's default `malloc()` for all non-GC allocations.
|
||||||
|
|
||||||
|
This yields a **5–12% wall-clock improvement** on evaluation workloads,
|
||||||
|
ranging from `nix-instantiate hello` to `nix-env -qa` and full NixOS
|
||||||
|
configurations.
|
||||||
|
|
||||||
|
The allocator can be disabled at build time with `-Dmimalloc=disabled`,
|
||||||
|
or by passing the `useMimalloc = false` override to the `lix` package.
|
||||||
@@ -172,6 +172,7 @@ nix = executable(
|
|||||||
dependencies : [
|
dependencies : [
|
||||||
liblix,
|
liblix,
|
||||||
boehm,
|
boehm,
|
||||||
|
mimalloc,
|
||||||
capnp_rpc,
|
capnp_rpc,
|
||||||
nlohmann_json,
|
nlohmann_json,
|
||||||
kj,
|
kj,
|
||||||
|
|||||||
@@ -352,6 +352,8 @@ gc_opt = get_option('gc').disable_if(
|
|||||||
boehm = dependency('bdw-gc', required : gc_opt, version : '>=8.2.6', include_type : 'system')
|
boehm = dependency('bdw-gc', required : gc_opt, version : '>=8.2.6', include_type : 'system')
|
||||||
configdata.set('HAVE_BOEHMGC', boehm.found().to_int())
|
configdata.set('HAVE_BOEHMGC', boehm.found().to_int())
|
||||||
|
|
||||||
|
mimalloc = dependency('mimalloc', required: get_option('mimalloc'))
|
||||||
|
|
||||||
boost = dependency('boost', required : true, include_type : 'system')
|
boost = dependency('boost', required : true, include_type : 'system')
|
||||||
kj = dependency('kj-async', required : true, include_type : 'system')
|
kj = dependency('kj-async', required : true, include_type : 'system')
|
||||||
capnp = dependency('capnp', required : true, include_type : 'system')
|
capnp = dependency('capnp', required : true, include_type : 'system')
|
||||||
|
|||||||
@@ -8,6 +8,10 @@ option('gc', type : 'feature',
|
|||||||
description : 'enable garbage collection in the Nix expression evaluator (requires Boehm GC)',
|
description : 'enable garbage collection in the Nix expression evaluator (requires Boehm GC)',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
option('mimalloc', type: 'feature', value: 'auto',
|
||||||
|
description: 'link against mimalloc to override the default memory allocator',
|
||||||
|
)
|
||||||
|
|
||||||
option('enable-embedded-sandbox-shell', type : 'boolean', value : false,
|
option('enable-embedded-sandbox-shell', type : 'boolean', value : false,
|
||||||
description : 'include the sandbox shell in the Nix binary',
|
description : 'include the sandbox shell in the Nix binary',
|
||||||
)
|
)
|
||||||
|
|||||||
+7
-1
@@ -42,6 +42,7 @@
|
|||||||
cacert,
|
cacert,
|
||||||
mercurial,
|
mercurial,
|
||||||
meson,
|
meson,
|
||||||
|
mimalloc,
|
||||||
ninja,
|
ninja,
|
||||||
openssl,
|
openssl,
|
||||||
passt,
|
passt,
|
||||||
@@ -75,6 +76,9 @@
|
|||||||
|
|
||||||
# Support garbage collection in the evaluator.
|
# Support garbage collection in the evaluator.
|
||||||
enableGC ? sanitize == null || !builtins.elem "address" sanitize,
|
enableGC ? sanitize == null || !builtins.elem "address" sanitize,
|
||||||
|
# Whether to use mimalloc over the default `malloc`
|
||||||
|
# Significantly improves evaluation performance on allocation-heavy workloads
|
||||||
|
useMimalloc ? true,
|
||||||
# List of Meson sanitize options. Accepts values of b_sanitize, e.g.
|
# List of Meson sanitize options. Accepts values of b_sanitize, e.g.
|
||||||
# "address", "undefined", "thread".
|
# "address", "undefined", "thread".
|
||||||
# Enabling the "address" sanitizer will disable garbage collection in the evaluator.
|
# Enabling the "address" sanitizer will disable garbage collection in the evaluator.
|
||||||
@@ -467,6 +471,7 @@ stdenv.mkDerivation (finalAttrs: {
|
|||||||
# so we must explicitly enable or disable features that we are not passing
|
# so we must explicitly enable or disable features that we are not passing
|
||||||
# dependencies for.
|
# dependencies for.
|
||||||
(lib.mesonEnable "gc" enableGC)
|
(lib.mesonEnable "gc" enableGC)
|
||||||
|
(lib.mesonEnable "mimalloc" useMimalloc)
|
||||||
(lib.mesonEnable "internal-api-docs" internalApiDocs)
|
(lib.mesonEnable "internal-api-docs" internalApiDocs)
|
||||||
(lib.mesonEnable "dtrace-probes" withDtrace)
|
(lib.mesonEnable "dtrace-probes" withDtrace)
|
||||||
(lib.mesonBool "enable-tests" (finalAttrs.finalPackage.doCheck || lintInsteadOfBuild))
|
(lib.mesonBool "enable-tests" (finalAttrs.finalPackage.doCheck || lintInsteadOfBuild))
|
||||||
@@ -574,7 +579,8 @@ stdenv.mkDerivation (finalAttrs: {
|
|||||||
++ lib.optionals (finalAttrs.dontBuild) maybePropagatedInputs
|
++ lib.optionals (finalAttrs.dontBuild) maybePropagatedInputs
|
||||||
# I am so sorry. This is because checkInputs are required to pass
|
# I am so sorry. This is because checkInputs are required to pass
|
||||||
# configure, but we don't actually want to *run* the checks here.
|
# configure, but we don't actually want to *run* the checks here.
|
||||||
++ lib.optionals lintInsteadOfBuild finalAttrs.checkInputs;
|
++ lib.optionals lintInsteadOfBuild finalAttrs.checkInputs
|
||||||
|
++ lib.optional useMimalloc mimalloc;
|
||||||
|
|
||||||
checkInputs = [
|
checkInputs = [
|
||||||
gtest
|
gtest
|
||||||
|
|||||||
Reference in New Issue
Block a user