libexpr: enable parallel marking in boehm-gc

Using parallel marking in GC speeds up evaluation a fair bit

```
Benchmark 1: ./lix-main/bin/nix search nixpkgs hello --no-eval-cache
  Time (mean ± σ):     20.740 s ±  0.046 s    [User: 17.583 s, System: 3.062 s]
  Range (min … max):   20.678 s … 20.794 s    10 runs

Benchmark 2: ./lix-parallel-marking/bin/nix search nixpkgs hello --no-eval-cache
  Time (mean ± σ):     15.037 s ±  0.080 s    [User: 19.602 s, System: 3.125 s]
  Range (min … max):   14.960 s … 15.227 s    10 runs

Summary
  ./lix-parallel-marking/bin/nix search nixpkgs hello --no-eval-cache ran
    1.38 ± 0.01 times faster than ./lix-main/bin/nix search nixpkgs hello --no-eval-cache
```

Based-on: https://github.com/NixOS/nix/pull/13708
Co-authored-by: Eelco Dolstra <edolstra@gmail.com>
Change-Id: Ibc7625f21e0ee7c8ad66203eeb3aca5d83977731
This commit is contained in:
Seth Flynn
2025-10-01 23:07:28 +00:00
committed by eldritch horrors
co-authored by Eelco Dolstra
parent 1c4e77387a
commit f1ef994f12
4 changed files with 49 additions and 2 deletions
+5
View File
@@ -86,6 +86,11 @@ ericson:
display_name: John Ericson
github: ericson2314
getchoo:
display_name: Seth Flynn
forgejo: getchoo
github: getchoo
gilice:
forgejo: gilice
+9
View File
@@ -0,0 +1,9 @@
---
synopsis: Lix now enables parallel marking in boehm-gc
issues: [fj#983]
cls: [3880]
category: Improvements
credits: [edolstra, getchoo]
---
This brings a fairly modest performance improvement (~38% for `nixpkgs search hello`) to evaluation, especially in scenarios that necessitate larger heap sizes.
+18
View File
@@ -43,6 +43,21 @@
#include <sys/resource.h>
#include <boost/container/small_vector.hpp>
// Ignore all internal signals boehm uses for parallel marking
// FIXME: Find out how to do this with LLDB for macOS!
#ifndef __APPLE__
[[gnu::section(".debug_gdb_scripts"), gnu::used]]
// TODO: We should use `SECTION_SCRIPT_ID_PYTHON_TEXT` from
// `<gdb/section-scripts.h>` instead of hardcoding 4.
// But why isn't this header exported by GDB?
static const char printer_script[] =
"\4"
R"(lix-ignore-boehm-signals
import gdb
gdb.execute("handle SIGPWR SIGXCPU ignore")
)";
#endif
#if HAVE_BOEHMGC
#define GC_INCLUDE_NEW
@@ -161,6 +176,9 @@ void initLibExpr()
GC_INIT();
// Enable parallel marking
GC_start_mark_threads();
GC_set_oom_fn(oomHandler);
/* Set the initial heap size to something fairly big (25% of
+17 -2
View File
@@ -95,7 +95,20 @@
versionJson = builtins.fromJSON (builtins.readFile ./version.json);
boehmgc-nix = boehmgc.override { enableLargeConfig = true; };
boehmgc-nix = (boehmgc.override { enableLargeConfig = true; }).overrideAttrs (oldAttrs: {
/*
TODO: Use the `initialMarkStackSize` override when
https://github.com/NixOS/nixpkgs/pull/439943 hits a stable branch
Increase the initial mark stack size to avoid stack
overflows, since these inhibit parallel marking (see
GC_mark_some()). To check whether the mark stack is too
small, run Nix with GC_PRINT_STATS=1 and look for messages
such as `Mark stack overflow`, `No room to copy back mark
stack`, and `Grew mark stack to ... frames`.
*/
NIX_CFLAGS_COMPILE = (oldAttrs.NIX_CFLAGS_COMPILE or "") + " -DINITIAL_MARK_STACK_SIZE=1048576";
});
editline-lix = editline.overrideAttrs (prev: {
configureFlags = (prev.configureFlags or [ ]) ++ [
@@ -469,7 +482,9 @@ stdenv.mkDerivation (finalAttrs: {
runHook postInstallCheck
'';
separateDebugInfo = !hostPlatform.isStatic && !finalAttrs.dontBuild;
# NOTE: This is disabled everywhere except Darwin due to Nixpkgs
# corrupting `.debug_gdb_scripts` segments (which currently aren't used on Darwin)
separateDebugInfo = !hostPlatform.isStatic && !finalAttrs.dontBuild && hostPlatform.isDarwin;
strictDeps = true;