mimalloc icon indicating copy to clipboard operation
mimalloc copied to clipboard

Potential Performance Regression with `dev3`

Open kamulos opened this issue 6 months ago • 3 comments

I just did a very quick tests with multithreaded allocation and deallocation. In this the dev3 branch does not perform very well. My CPU is 13th Gen Intel(R) Core(TM) i7-13850HX. The test code is in Rust, I hope this is ok:

# Cargo.toml

[package]
name = "experiment"
edition = "2021"

[dependencies]
rand = "0.9.1"
// main.rs

use rand::{rngs::ThreadRng, Rng};
use std::{hint::black_box, thread, time::Instant};

fn main() {
    let start = Instant::now();

    thread::scope(|scope| {
        for _ in 0..100 {
            scope.spawn(|| {
                let mut rnd = ThreadRng::default();
                for _ in 0..1000000 {
                    let allocation = vec![0u8; rnd.random_range(1..1000)];
                    black_box(&allocation);
                    if rnd.random_bool(0.24) {
                        allocation.leak();
                    }
                }
            });
        }
    });

    let duration = start.elapsed();
    println!("took {}", duration.as_secs_f32());
}

My results are (built in --release mode):

❯ LD_PRELOAD=/usr/lib/libjemalloc.so.2 ./experiment
took 0.6000622

❯ LD_PRELOAD=/home/abc/temp/mimalloc/build/libmimalloc.so.1.9 ./experiment
took 0.63197255

❯ LD_PRELOAD=/home/abc/temp/mimalloc/build/libmimalloc.so.2.2 ./experiment
took 0.62372595

❯ LD_PRELOAD=/home/abc/temp/mimalloc/build/libmimalloc.so.3.1 ./experiment
took 4.9627113

kamulos avatar Jun 17 '25 09:06 kamulos

Thanks -- something strange is going on as v3 should not be that much slower. What platform are you using? Is this v3.1.5 ? I rewrote the test in C++ to make sure the malloc/free calls are explicit; when I run this on macOS there is no difference in execution time between mimalloc v2 and v3. So, it may be a Linux specific thing, or perhaps something with Rust that causes the strange slowdown. Can you check if my C++ reflects your test accurately? I added the summing to make sure the allocation etc does not get optimized away:

static std::atomic<long> gsum;

static void local_alloc() {
  long sum = 0;
  for(int i = 0; i < 1000000; i++) {
    const int n = 1 + std::rand() % 1000;
    uint8_t* p = (uint8_t*)calloc(n, 1);
    p[0] = 1;
    sum += p[std::rand() % n];
    if ((std::rand() % 100) > 24) {
      free(p);
    }
  }
  gsum += sum;
}

static void test_thread_leak() {
  std::vector<std::thread> threads;
  for (int i=1; i<=100; ++i) {
    threads.emplace_back(std::thread(&local_alloc));
  }
  for (auto& th : threads) {
    th.join();
  }
}

ps. Maybe run the v3 test with MIMALLOC_VERBOSE=1 to see if it was compiled with debug info on or something?

daanx avatar Jun 17 '25 12:06 daanx

What platform are you using?

Arch Linux with Kernel 6.15: Linux ... 6.15.2-arch1-1 #1 SMP PREEMPT_DYNAMIC Tue, 10 Jun 2025 21:32:33 +0000 x86_64 GNU/Linux

Is this v3.1.5 ?

mimalloc: v3.1.6, release, git v3.1.5-1-gdc84ea78 (built on Jun 17 2025, 09:39:45)

Can you check if my C++ reflects your test accurately?

The Code seems fine to me, but it behaves wildly differently. Your Code takes 60s with mimalloc v2 while my Rust Code takes 0.6s with mimalloc v2. I am using clang 20 vs Rust nightly, which should basically be the same optimizations. I even replicated the summing in my Rust code, no difference.

So either this is some aggressive opimizations, that only trigger in the Rust code for some reason or it has something to do with the random number generation.

Either way, there is an issue with the mimalloc using the Rust binary, independent of how much work actually happens there and how much got somehow optimized away. I am just not sure how to dig into it further.

Rust Binary with Mimalloc 2.2
mimalloc: v2.2.5, release, git v2.2.4-37-g09a27098 (built on Jun 17 2025, 09:38:16)
mimalloc: option 'show_errors': 0 
mimalloc: option 'show_stats': 0 
mimalloc: option 'verbose': 1 
mimalloc: option 'eager_commit': 1 
mimalloc: option 'arena_eager_commit': 2 
mimalloc: option 'purge_decommits': 1 
mimalloc: option 'allow_large_os_pages': 2 
mimalloc: option 'reserve_huge_os_pages': 0 
mimalloc: option 'reserve_huge_os_pages_at': -1 
mimalloc: option 'reserve_os_memory': 0 KiB
mimalloc: option 'deprecated_segment_cache': 0 
mimalloc: option 'deprecated_page_reset': 0 
mimalloc: option 'abandoned_page_purge': 0 
mimalloc: option 'deprecated_segment_reset': 0 
mimalloc: option 'eager_commit_delay': 1 
mimalloc: option 'purge_delay': 10 
mimalloc: option 'use_numa_nodes': 0 
mimalloc: option 'disallow_os_alloc': 0 
mimalloc: option 'os_tag': 100 
mimalloc: option 'max_errors': 32 
mimalloc: option 'max_warnings': 32 
mimalloc: option 'max_segment_reclaim': 10 
mimalloc: option 'destroy_on_exit': 0 
mimalloc: option 'arena_reserve': 1048576 KiB
mimalloc: option 'arena_purge_mult': 10 
mimalloc: option 'purge_extend_delay': 1 
mimalloc: option 'abandoned_reclaim_on_free': 0 
mimalloc: option 'disallow_arena_alloc': 0 
mimalloc: option 'retry_on_oom': 400 
mimalloc: option 'visit_abandoned': 0 
mimalloc: option 'guarded_min': 0 
mimalloc: option 'guarded_max': 1073741824 
mimalloc: option 'guarded_precise': 0 
mimalloc: option 'guarded_sample_rate': 0 
mimalloc: option 'guarded_sample_seed': 0 
mimalloc: option 'target_segments_per_thread': 0 
mimalloc: option 'generic_collect': 10000 
mimalloc: debug level : 0
mimalloc: secure level: 0
mimalloc: mem tracking: none
mimalloc: process init: 0x7FBAF2FC6F80
mimalloc: using 1 numa regions
mimalloc: reserved 1048576 KiB memory
mimalloc: reserved 1048576 KiB memory
mimalloc: reserved 1048576 KiB memory
mimalloc: reserved 1048576 KiB memory
mimalloc: reserved 1048576 KiB memory
mimalloc: reserved 1048576 KiB memory
mimalloc: reserved 1048576 KiB memory
mimalloc: reserved 1048576 KiB memory
mimalloc: warning: thread 0x7FBAEC47D6C0: unable to allocate aligned OS memory directly, fall back to over-allocation (size: 0x80000000 bytes, address: 0x7FBA66600000, alignment: 0x2000000, commit: 1)
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
took 0.6289115
heap stats:     peak       total     current       block      total#   
  reserved:    56.0 GiB    58.0 GiB    56.0 GiB                          
 committed:    55.9 GiB    58.0 GiB    55.8 GiB                          
     reset:     0      
    purged:   134.6 MiB
   touched:    32.5 MiB    33.0 MiB    31.7 MiB                          
  segments:     1.0 Ki      1.1 Ki    139                                not all freed
-abandoned:   926         926         262                                not all freed
   -cached:     0           0           0                                ok
     pages:     0           0        -336                                not all freed
-abandoned:   456.8 Ki    456.8 Ki    127.8 Ki                           not all freed
 -extended:     0      
   -retire:     0      
    arenas:    32      
 -rollback:     0      
     mmaps:   148      
   commits:     0      
    resets:     0      
    purges:    19      
   guarded:     0      
   threads:    99         100           0                                ok
  searches:     0.0 avg
numa nodes:     1
   elapsed:     0.629 s
   process: user: 10.722 s, system: 5.310 s, faults: 0, rss: 12.3 GiB, commit: 55.9 GiB
mimalloc: process done: 0x7FBAF2FC6F80
Rust Binary with Mimalloc 3.1
mimalloc: v3.1.6, release, git v3.1.5-1-gdc84ea78 (built on Jun 17 2025, 09:39:45)
mimalloc: option 'show_errors': 0 
mimalloc: option 'show_stats': 0 
mimalloc: option 'verbose': 1 
mimalloc: option 'eager_commit': 1 
mimalloc: option 'arena_eager_commit': 2 
mimalloc: option 'purge_decommits': 1 
mimalloc: option 'allow_large_os_pages': 2 
mimalloc: option 'reserve_huge_os_pages': 0 
mimalloc: option 'reserve_huge_os_pages_at': -1 
mimalloc: option 'reserve_os_memory': 0 KiB
mimalloc: option 'deprecated_segment_cache': 0 
mimalloc: option 'deprecated_page_reset': 0 
mimalloc: option 'abandoned_page_purge': 0 
mimalloc: option 'deprecated_segment_reset': 0 
mimalloc: option 'eager_commit_delay': 1 
mimalloc: option 'purge_delay': 1000 
mimalloc: option 'use_numa_nodes': 0 
mimalloc: option 'disallow_os_alloc': 0 
mimalloc: option 'os_tag': 100 
mimalloc: option 'max_errors': 32 
mimalloc: option 'max_warnings': 32 
mimalloc: option 'deprecated_max_segment_reclaim': 10 
mimalloc: option 'destroy_on_exit': 0 
mimalloc: option 'arena_reserve': 1048576 KiB
mimalloc: option 'arena_purge_mult': 1 
mimalloc: option 'deprecated_purge_extend_delay': 1 
mimalloc: option 'disallow_arena_alloc': 0 
mimalloc: option 'retry_on_oom': 400 
mimalloc: option 'visit_abandoned': 0 
mimalloc: option 'guarded_min': 0 
mimalloc: option 'guarded_max': 1073741824 
mimalloc: option 'guarded_precise': 0 
mimalloc: option 'guarded_sample_rate': 0 
mimalloc: option 'guarded_sample_seed': 0 
mimalloc: option 'generic_collect': 10000 
mimalloc: option 'page_reclaim_on_free': 0 
mimalloc: option 'page_full_retain': 2 
mimalloc: option 'page_max_candidates': 4 
mimalloc: option 'max_vabits': 0 
mimalloc: option 'pagemap_commit': 0 
mimalloc: option 'page_commit_on_demand': 0 
mimalloc: option 'page_max_reclaim': -1 
mimalloc: option 'page_cross_thread_max_reclaim': 32 
mimalloc: debug level : 0
mimalloc: secure level: 0
mimalloc: mem tracking: none
mimalloc: process init: 0x7F8A2166AF80
mimalloc: reserved 1048576 KiB memory
mimalloc: using 1 numa regions
mimalloc: using 1 numa regions
mimalloc: using 1 numa regions
mimalloc: reserved 1048576 KiB memory
mimalloc: reserved 1048576 KiB memory
mimalloc: reserved 1048576 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 4194304 KiB memory
took 4.6002703
heap stats:     peak       total     current       block      total#   
  reserved:    16.0 GiB    16.0 GiB    16.0 GiB                          
 committed:    12.2 GiB    12.2 GiB    12.2 GiB                          
     reset:     0      
    purged:     0      
   touched:     0           0           0                                ok
     pages:   196.6 Ki    807.8 Ki    196.3 Ki                           not all freed
-abandoned:   196.6 Ki    755.2 Ki    196.3 Ki                           not all freed
 -reclaima:     1.8 Ki 
 -reclaimf:   557.0 Ki 
-reabandon:     0      
    -waits:     0      
 -extended:     0      
   -retire:     0      
    arenas:     9      
 -rollback:     0      
     mmaps:   658      
   commits:     0      
    resets:     0      
    purges:     0      
   guarded:     0      
   threads:   100         100           0                                ok
  searches:     1.0 avg
numa nodes:     1
   elapsed:     4.601 s
   process: user: 19.448 s, system: 103.406 s, faults: 0, rss: 12.2 GiB, commit: 12.2 GiB
mimalloc: process done: 0x7F8A2166AF80
C++ Binary with Mimalloc 2.2
mimalloc: process init: 0x7FD4CE100780
mimalloc: using 1 numa regions
mimalloc: v2.2.5, release, git v2.2.4-37-g09a27098 (built on Jun 17 2025, 09:38:16)
mimalloc: option 'show_errors': 0 
mimalloc: option 'show_stats': 0 
mimalloc: option 'verbose': 1 
mimalloc: option 'eager_commit': 1 
mimalloc: option 'arena_eager_commit': 2 
mimalloc: option 'purge_decommits': 1 
mimalloc: option 'allow_large_os_pages': 2 
mimalloc: option 'reserve_huge_os_pages': 0 
mimalloc: option 'reserve_huge_os_pages_at': -1 
mimalloc: option 'reserve_os_memory': 0 KiB
mimalloc: option 'deprecated_segment_cache': 0 
mimalloc: option 'deprecated_page_reset': 0 
mimalloc: option 'abandoned_page_purge': 0 
mimalloc: option 'deprecated_segment_reset': 0 
mimalloc: option 'eager_commit_delay': 1 
mimalloc: option 'purge_delay': 10 
mimalloc: option 'use_numa_nodes': 0 
mimalloc: option 'disallow_os_alloc': 0 
mimalloc: option 'os_tag': 100 
mimalloc: option 'max_errors': 32 
mimalloc: option 'max_warnings': 32 
mimalloc: option 'max_segment_reclaim': 10 
mimalloc: option 'destroy_on_exit': 0 
mimalloc: option 'arena_reserve': 1048576 KiB
mimalloc: option 'arena_purge_mult': 10 
mimalloc: option 'purge_extend_delay': 1 
mimalloc: option 'abandoned_reclaim_on_free': 0 
mimalloc: option 'disallow_arena_alloc': 0 
mimalloc: option 'retry_on_oom': 400 
mimalloc: option 'visit_abandoned': 0 
mimalloc: option 'guarded_min': 0 
mimalloc: option 'guarded_max': 1073741824 
mimalloc: option 'guarded_precise': 0 
mimalloc: option 'guarded_sample_rate': 0 
mimalloc: option 'guarded_sample_seed': 0 
mimalloc: option 'target_segments_per_thread': 0 
mimalloc: option 'generic_collect': 10000 
mimalloc: debug level : 0
mimalloc: secure level: 0
mimalloc: mem tracking: none
mimalloc: reserved 1048576 KiB memory
mimalloc: reserved 1048576 KiB memory
mimalloc: reserved 1048576 KiB memory
mimalloc: reserved 1048576 KiB memory
mimalloc: reserved 1048576 KiB memory
mimalloc: reserved 1048576 KiB memory
mimalloc: reserved 1048576 KiB memory
mimalloc: reserved 1048576 KiB memory
mimalloc: warning: thread 0x7FD4BB2F26C0: unable to allocate aligned OS memory directly, fall back to over-allocation (size: 0x80000000 bytes, address: 0x7FD41BA00000, alignment: 0x2000000, commit: 1)
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
heap stats:     peak       total     current       block      total#   
  reserved:    16.0 GiB    18.0 GiB    16.0 GiB                          
 committed:    15.7 GiB    18.0 GiB    14.8 GiB                          
     reset:     0      
    purged:     1.1 GiB
   touched:    31.1 MiB    31.2 MiB    30.1 MiB                          
  segments:   680         715           1                                not all freed
-abandoned:   678         679         464                                not all freed
   -cached:     0           0           0                                ok
     pages:     0           0        -292                                not all freed
-abandoned:   297.3 Ki    297.4 Ki    205.4 Ki                           not all freed
 -extended:     0      
   -retire:     0      
    arenas:    12      
 -rollback:     0      
     mmaps:   115      
   commits:     0      
    resets:     0      
    purges:    51      
   guarded:     0      
   threads:   100         100           0                                ok
  searches:     0.0 avg
numa nodes:     1
   elapsed:    58.740 s
   process: user: 92.683 s, system: 1532.769 s, faults: 0, rss: 12.8 GiB, commit: 15.7 GiB
mimalloc: process done: 0x7FD4CE100780
C++ Binary with Mimalloc 3.1
mimalloc: process init: 0x7FB3A7CCF780
mimalloc: warning: unable to allocate aligned OS memory directly, fall back to over-allocation (size: 0x20000 bytes, address: 0x7FB3A7E07000, alignment: 0x10000, commit: 1)
mimalloc: v3.1.6, release, git v3.1.5-1-gdc84ea78 (built on Jun 17 2025, 09:39:45)
mimalloc: option 'show_errors': 0 
mimalloc: option 'show_stats': 0 
mimalloc: option 'verbose': 1 
mimalloc: option 'eager_commit': 1 
mimalloc: option 'arena_eager_commit': 2 
mimalloc: option 'purge_decommits': 1 
mimalloc: option 'allow_large_os_pages': 2 
mimalloc: option 'reserve_huge_os_pages': 0 
mimalloc: option 'reserve_huge_os_pages_at': -1 
mimalloc: option 'reserve_os_memory': 0 KiB
mimalloc: option 'deprecated_segment_cache': 0 
mimalloc: option 'deprecated_page_reset': 0 
mimalloc: option 'abandoned_page_purge': 0 
mimalloc: option 'deprecated_segment_reset': 0 
mimalloc: option 'eager_commit_delay': 1 
mimalloc: option 'purge_delay': 1000 
mimalloc: option 'use_numa_nodes': 0 
mimalloc: option 'disallow_os_alloc': 0 
mimalloc: option 'os_tag': 100 
mimalloc: option 'max_errors': 32 
mimalloc: option 'max_warnings': 32 
mimalloc: option 'deprecated_max_segment_reclaim': 10 
mimalloc: option 'destroy_on_exit': 0 
mimalloc: option 'arena_reserve': 1048576 KiB
mimalloc: option 'arena_purge_mult': 1 
mimalloc: option 'deprecated_purge_extend_delay': 1 
mimalloc: option 'disallow_arena_alloc': 0 
mimalloc: option 'retry_on_oom': 400 
mimalloc: option 'visit_abandoned': 0 
mimalloc: option 'guarded_min': 0 
mimalloc: option 'guarded_max': 1073741824 
mimalloc: option 'guarded_precise': 0 
mimalloc: option 'guarded_sample_rate': 0 
mimalloc: option 'guarded_sample_seed': 0 
mimalloc: option 'generic_collect': 10000 
mimalloc: option 'page_reclaim_on_free': 0 
mimalloc: option 'page_full_retain': 2 
mimalloc: option 'page_max_candidates': 4 
mimalloc: option 'max_vabits': 0 
mimalloc: option 'pagemap_commit': 0 
mimalloc: option 'page_commit_on_demand': 0 
mimalloc: option 'page_max_reclaim': -1 
mimalloc: option 'page_cross_thread_max_reclaim': 32 
mimalloc: debug level : 0
mimalloc: secure level: 0
mimalloc: mem tracking: none
mimalloc: reserved 1048576 KiB memory
mimalloc: using 1 numa regions
mimalloc: reserved 1048576 KiB memory
mimalloc: reserved 1048576 KiB memory
mimalloc: reserved 1048576 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 2097152 KiB memory
mimalloc: reserved 4194304 KiB memory
heap stats:     peak       total     current       block      total#   
  reserved:    16.0 GiB    16.0 GiB    16.0 GiB                          
 committed:    12.7 GiB    12.7 GiB    12.7 GiB                          
     reset:     0      
    purged:     1.0 MiB
   touched:     0           0           0                                ok
     pages:   205.1 Ki    805.4 Ki    204.8 Ki                           not all freed
-abandoned:   205.1 Ki    749.3 Ki    204.8 Ki                           not all freed
 -reclaima:     1.1 Ki 
 -reclaimf:   543.3 Ki 
-reabandon:     0      
    -waits:     0      
 -extended:     0      
   -retire:     0      
    arenas:     9      
 -rollback:     0      
     mmaps:   121      
   commits:     0      
    resets:     0      
    purges:    15      
   guarded:     0      
   threads:   100         100           0                                ok
  searches:     1.0 avg
numa nodes:     1
   elapsed:    65.140 s
   process: user: 105.080 s, system: 1692.281 s, faults: 0, rss: 12.7 GiB, commit: 12.7 GiB
mimalloc: process done: 0x7FB3A7CCF780

kamulos avatar Jun 20 '25 12:06 kamulos

I am not sure how to interpret it correctly, but I noticed, that in the Rust binary, reserved/committed and mmaps have a big difference beween v2 and v3

kamulos avatar Jun 20 '25 12:06 kamulos

I came across the same performance issues when upgrading from to v3, and I've been able to replicate similar results on both Linux (AMD Ryzen 3900x) and MacOS (ARM M1) using similar examples derived from the above. And then did some further digging... I don't have a smoking gun, but this might get us a bit closer. I hope this helps!

Setup

  • AMD Ryzen 3900X running Linux under WSL
  • Broadly similar results on M1 Macbook under OSX
  • Broadly similar results on C++ side with both gcc and clang

I modified the benchmarks a bit to better reflect one of my own use cases where I noticed the performance regression in the first place. I also used a fast thread-local random number generator in C++, as the (shared?) rand() call used in the example above was responsible for the difference between Rust and C++ results. Now they're very close.

Note that I'm also using mi_zalloc_aligned in C++ because this is the function called from Rust when allocating a large zeroed vec. More on that below.

Code is here: C++ / Rust

C++ (cpp-bench)

  • mimalloc v2 took: 708 ms
  • mimalloc v3 took: 8201 ms

Rust (rust-bench)

  • mimalloc v2 took: 731 ms
  • mimalloc v3 took: 8242 ms

Profiling

Using perf on the Rust build reveals ~50% of cycles spent in memset. Changing the call in C++ from mi_zalloc_aligned to mi_malloc_aligned reduces the runtime significantly in the mimalloc v3 case.

With V3:

  • mi_zalloc_aligned: 8201 ms (as above - matches Rust use)
  • mi_malloc_aligned: 427 ms

Although, of course, the results are then incorrect as we're expecting a zeroed allocation. But it does hint that the problem is related to zeroing out the allocated chunk in v3. We're doing the same thing in v2, but it's a lot faster.

Note that the same results as mi_zalloc_aligned are obtained if we use mi_malloc_aligned and then zero the allocated memory using memset. Similar results if I zero the array using AVX2 writes, so it's not as if the zeroing itself is slow either.

Given the above, it seems like this might be a cache coherence thing. If new allocations aren't as local as they were in v2 and often come from memory previously used by a different core, then perhaps what we're seeing here is the cost of that.

Run logs

cpp mimalloc v2

mimalloc: process init: 0x72EDFC8DE740
mimalloc: using 1 numa regions
mimalloc: v2.2.4, release (built on Dec  6 2025, 22:05:44)
mimalloc: option 'show_errors': 0 
mimalloc: option 'show_stats': 1 
mimalloc: option 'verbose': 1 
mimalloc: option 'eager_commit': 1 
mimalloc: option 'arena_eager_commit': 2 
mimalloc: option 'purge_decommits': 1 
mimalloc: option 'allow_large_os_pages': 2 
mimalloc: option 'reserve_huge_os_pages': 0 
mimalloc: option 'reserve_huge_os_pages_at': -1 
mimalloc: option 'reserve_os_memory': 0 KiB
mimalloc: option 'deprecated_segment_cache': 0 
mimalloc: option 'deprecated_page_reset': 0 
mimalloc: option 'abandoned_page_purge': 0 
mimalloc: option 'deprecated_segment_reset': 0 
mimalloc: option 'eager_commit_delay': 1 
mimalloc: option 'purge_delay': 10 
mimalloc: option 'use_numa_nodes': 0 
mimalloc: option 'disallow_os_alloc': 0 
mimalloc: option 'os_tag': 100 
mimalloc: option 'max_errors': 32 
mimalloc: option 'max_warnings': 32 
mimalloc: option 'max_segment_reclaim': 10 
mimalloc: option 'destroy_on_exit': 0 
mimalloc: option 'arena_reserve': 1048576 KiB
mimalloc: option 'arena_purge_mult': 10 
mimalloc: option 'purge_extend_delay': 1 
mimalloc: option 'abandoned_reclaim_on_free': 0 
mimalloc: option 'disallow_arena_alloc': 0 
mimalloc: option 'retry_on_oom': 400 
mimalloc: option 'visit_abandoned': 0 
mimalloc: option 'guarded_min': 0 
mimalloc: option 'guarded_max': 1073741824 
mimalloc: option 'guarded_precise': 0 
mimalloc: option 'guarded_sample_rate': 0 
mimalloc: option 'guarded_sample_seed': 0 
mimalloc: option 'target_segments_per_thread': 0 
mimalloc: option 'generic_collect': 10000 
mimalloc: debug level : 0
mimalloc: secure level: 0
mimalloc: mem tracking: none
mimalloc: reserved 1048576 KiB memory
mimalloc: reserved 1048576 KiB memory
heap stats:     peak       total     current       block      total#   
  reserved:     2.0 GiB     2.0 GiB     2.0 GiB                          
 committed:     2.0 GiB     2.0 GiB     2.0 GiB                          
     reset:     0      
    purged:     0      
   touched:    75.8 MiB   101.1 MiB  -561.3 GiB                          
  segments:     1.1 Ki      1.5 Ki      1                                not all freed
-abandoned:     3          10           1                                not all freed
   -cached:     0           0           0                                ok
     pages:     0           0          -2.8 Mi                           not all freed
-abandoned:     3          10           1                                not all freed
 -extended:     0      
   -retire:     0      
    arenas:     2      
 -rollback:     0      
     mmaps:    28      
   commits:     0      
    resets:     0      
    purges:     0      
   guarded:     0      
   threads:    24          24           0                                ok
  searches:     0.0 avg
numa nodes:     1
   elapsed:     0.698 s
   process: user: 16.218 s, system: 0.051 s, faults: 0, rss: 23.8 MiB, commit: 2.0 GiB
mimalloc: process done: 0x72EDFC8DE740
........................
took: 697 ms
gsum: 3935

cpp mimalloc v3

mimalloc: process init: 0x74B7A70D5780
mimalloc: warning: unable to allocate aligned OS memory directly, fall back to over-allocation (size: 0x20000 bytes, address: 0x74B7A70B5000, alignment: 0x10000, commit: 1)
mimalloc: v3.1.5, release (built on Dec  6 2025, 22:09:34)
mimalloc: option 'show_errors': 0 
mimalloc: option 'show_stats': 1 
mimalloc: option 'verbose': 1 
mimalloc: option 'eager_commit': 1 
mimalloc: option 'arena_eager_commit': 2 
mimalloc: option 'purge_decommits': 1 
mimalloc: option 'allow_large_os_pages': 2 
mimalloc: option 'reserve_huge_os_pages': 0 
mimalloc: option 'reserve_huge_os_pages_at': -1 
mimalloc: option 'reserve_os_memory': 0 KiB
mimalloc: option 'deprecated_segment_cache': 0 
mimalloc: option 'deprecated_page_reset': 0 
mimalloc: option 'abandoned_page_purge': 0 
mimalloc: option 'deprecated_segment_reset': 0 
mimalloc: option 'eager_commit_delay': 1 
mimalloc: option 'purge_delay': 1000 
mimalloc: option 'use_numa_nodes': 0 
mimalloc: option 'disallow_os_alloc': 0 
mimalloc: option 'os_tag': 100 
mimalloc: option 'max_errors': 32 
mimalloc: option 'max_warnings': 32 
mimalloc: option 'deprecated_max_segment_reclaim': 10 
mimalloc: option 'destroy_on_exit': 0 
mimalloc: option 'arena_reserve': 1048576 KiB
mimalloc: option 'arena_purge_mult': 1 
mimalloc: option 'deprecated_purge_extend_delay': 1 
mimalloc: option 'disallow_arena_alloc': 0 
mimalloc: option 'retry_on_oom': 400 
mimalloc: option 'visit_abandoned': 0 
mimalloc: option 'guarded_min': 0 
mimalloc: option 'guarded_max': 1073741824 
mimalloc: option 'guarded_precise': 0 
mimalloc: option 'guarded_sample_rate': 0 
mimalloc: option 'guarded_sample_seed': 0 
mimalloc: option 'generic_collect': 10000 
mimalloc: option 'page_reclaim_on_free': 0 
mimalloc: option 'page_full_retain': 2 
mimalloc: option 'page_max_candidates': 4 
mimalloc: option 'max_vabits': 0 
mimalloc: option 'pagemap_commit': 0 
mimalloc: option 'page_commit_on_demand': 0 
mimalloc: option 'page_max_reclaim': -1 
mimalloc: option 'page_cross_thread_max_reclaim': 32 
mimalloc: debug level : 0
mimalloc: secure level: 0
mimalloc: mem tracking: none
mimalloc: reserved 1048576 KiB memory
mimalloc: using 1 numa regions
heap stats:     peak       total     current       block      total#   
  reserved:     1.0 GiB     1.0 GiB     1.0 GiB                          
 committed:    58.3 MiB    58.5 MiB    32.5 MiB                          
     reset:     0      
    purged:    25.8 MiB
   touched:     0           0           0                                ok
     pages:     2.8 Mi      2.8 Mi      1                                not all freed
-abandoned:     1.1 Ki      2.8 Mi      1                                not all freed
 -reclaima:     4      
 -reclaimf:     0      
-reabandon:     0      
    -waits:     0      
 -extended:     0      
   -retire:     0      
    arenas:     1      
 -rollback:     0      
     mmaps:     6      
   commits:     0      
    resets:     0      
    purges:    95      
   guarded:     0      
   threads:    24          24           0                                ok
  searches:     1.0 avg
numa nodes:     1
   elapsed:     8.134 s
   process: user: 190.900 s, system: 0.236 s, faults: 0, rss: 21.5 MiB, commit: 58.3 MiB
mimalloc: process done: 0x74B7A70D5780
........................
took: 8134 ms
gsum: 3856

rust mimalloc v2

    Finished `release` profile [optimized] target(s) in 0.33s
     Running `/home/michael/projects/mimalloc-rust-tests/target/release/rust-bench`
mimalloc: v2.2.4 (built on Dec  6 2025, 16:20:36)
mimalloc: option 'show_errors': 0 
mimalloc: option 'show_stats': 1 
mimalloc: option 'verbose': 1 
mimalloc: option 'eager_commit': 1 
mimalloc: option 'arena_eager_commit': 2 
mimalloc: option 'purge_decommits': 1 
mimalloc: option 'allow_large_os_pages': 2 
mimalloc: option 'reserve_huge_os_pages': 0 
mimalloc: option 'reserve_huge_os_pages_at': -1 
mimalloc: option 'reserve_os_memory': 0 KiB
mimalloc: option 'deprecated_segment_cache': 0 
mimalloc: option 'deprecated_page_reset': 0 
mimalloc: option 'abandoned_page_purge': 0 
mimalloc: option 'deprecated_segment_reset': 0 
mimalloc: option 'eager_commit_delay': 1 
mimalloc: option 'purge_delay': 10 
mimalloc: option 'use_numa_nodes': 0 
mimalloc: option 'disallow_os_alloc': 0 
mimalloc: option 'os_tag': 100 
mimalloc: option 'max_errors': 32 
mimalloc: option 'max_warnings': 32 
mimalloc: option 'max_segment_reclaim': 10 
mimalloc: option 'destroy_on_exit': 0 
mimalloc: option 'arena_reserve': 1048576 KiB
mimalloc: option 'arena_purge_mult': 10 
mimalloc: option 'purge_extend_delay': 1 
mimalloc: option 'abandoned_reclaim_on_free': 0 
mimalloc: option 'disallow_arena_alloc': 0 
mimalloc: option 'retry_on_oom': 400 
mimalloc: option 'visit_abandoned': 0 
mimalloc: option 'guarded_min': 0 
mimalloc: option 'guarded_max': 1073741824 
mimalloc: option 'guarded_precise': 0 
mimalloc: option 'guarded_sample_rate': 0 
mimalloc: option 'guarded_sample_seed': 0 
mimalloc: option 'target_segments_per_thread': 0 
mimalloc: option 'generic_collect': 10000 
mimalloc: debug level : 0
mimalloc: secure level: 0
mimalloc: mem tracking: none
mimalloc: process init: 0x75D82775A780
mimalloc: using 1 numa regions
mimalloc: reserved 1048576 KiB memory
........................
took: 698
gsum: 3960
heap stats:     peak       total     current       block      total#   
  reserved:     1.0 GiB     1.0 GiB     1.0 GiB                          
 committed:     1.0 GiB     1.0 GiB   224.1 MiB                          
     reset:     0      
    purged:   799.8 MiB
   touched:    69.6 MiB    96.4 MiB  -560.5 GiB                          
  segments:     1.1 Ki      1.5 Ki      1                                not all freed
-abandoned:     3          11           0                                ok
   -cached:     0           0           0                                ok
     pages:     0           0          -2.8 Mi                           not all freed
-abandoned:     4          13           0                                ok
 -extended:     0      
   -retire:     0      
    arenas:     1      
 -rollback:     0      
     mmaps:    25      
   commits:     0      
    resets:     0      
    purges:     3      
   guarded:     0      
   threads:    24          24           0                                ok
  searches:     0.0 avg
numa nodes:     1
   elapsed:     0.699 s
   process: user: 16.312 s, system: 0.182 s, faults: 0, rss: 52.6 MiB, commit: 1.0 GiB
mimalloc: process done: 0x75D82775A780

rust mimalloc v3

mimalloc: v3.1.5 (built on Dec  6 2025, 16:21:16)
mimalloc: option 'show_errors': 0 
mimalloc: option 'show_stats': 1 
mimalloc: option 'verbose': 1 
mimalloc: option 'eager_commit': 1 
mimalloc: option 'arena_eager_commit': 2 
mimalloc: option 'purge_decommits': 1 
mimalloc: option 'allow_large_os_pages': 2 
mimalloc: option 'reserve_huge_os_pages': 0 
mimalloc: option 'reserve_huge_os_pages_at': -1 
mimalloc: option 'reserve_os_memory': 0 KiB
mimalloc: option 'deprecated_segment_cache': 0 
mimalloc: option 'deprecated_page_reset': 0 
mimalloc: option 'abandoned_page_purge': 0 
mimalloc: option 'deprecated_segment_reset': 0 
mimalloc: option 'eager_commit_delay': 1 
mimalloc: option 'purge_delay': 1000 
mimalloc: option 'use_numa_nodes': 0 
mimalloc: option 'disallow_os_alloc': 0 
mimalloc: option 'os_tag': 100 
mimalloc: option 'max_errors': 32 
mimalloc: option 'max_warnings': 32 
mimalloc: option 'deprecated_max_segment_reclaim': 10 
mimalloc: option 'destroy_on_exit': 0 
mimalloc: option 'arena_reserve': 1048576 KiB
mimalloc: option 'arena_purge_mult': 1 
mimalloc: option 'deprecated_purge_extend_delay': 1 
mimalloc: option 'disallow_arena_alloc': 0 
mimalloc: option 'retry_on_oom': 400 
mimalloc: option 'visit_abandoned': 0 
mimalloc: option 'guarded_min': 0 
mimalloc: option 'guarded_max': 1073741824 
mimalloc: option 'guarded_precise': 0 
mimalloc: option 'guarded_sample_rate': 0 
mimalloc: option 'guarded_sample_seed': 0 
mimalloc: option 'generic_collect': 10000 
mimalloc: option 'page_reclaim_on_free': 0 
mimalloc: option 'page_full_retain': 2 
mimalloc: option 'page_max_candidates': 4 
mimalloc: option 'max_vabits': 0 
mimalloc: option 'pagemap_commit': 0 
mimalloc: option 'page_commit_on_demand': 0 
mimalloc: option 'page_max_reclaim': -1 
mimalloc: option 'page_cross_thread_max_reclaim': 32 
mimalloc: debug level : 0
mimalloc: secure level: 0
mimalloc: mem tracking: none
mimalloc: process init: 0x79BBB2BAB7C0
mimalloc: reserved 1048576 KiB memory
mimalloc: using 1 numa regions
........................
took: 8212
gsum: 3906
heap stats:     peak       total     current       block      total#   
  reserved:     1.0 GiB     1.0 GiB     1.0 GiB                          
 committed:    64.6 MiB    64.6 MiB  -128.5 KiB                          
     reset:     0      
    purged:    64.7 MiB
   touched:     0           0           0                                ok
     pages:     2.8 Mi      2.8 Mi      2                                not all freed
-abandoned:     1.1 Ki      2.8 Mi      0                                ok
 -reclaima:     0      
 -reclaimf:     0      
-reabandon:     0      
    -waits:     0      
 -extended:     0      
   -retire:     0      
    arenas:     1      
 -rollback:     0      
     mmaps:     3      
   commits:     0      
    resets:     0      
    purges:   229      
   guarded:     0      
   threads:    24          24           0                                ok
  searches:     1.0 avg
numa nodes:     1
   elapsed:     8.217 s
   process: user: 193.125 s, system: 0.223 s, faults: 0, rss: 31.6 MiB, commit: 64.6 MiB
mimalloc: process done: 0x79BBB2BAB7C0

mike-barber avatar Dec 07 '25 03:12 mike-barber