Skip to content

Draft: implement malloc/free within the bump allocator, passing size with realloc and free - #23924

Draft
rainers wants to merge 3 commits into
dlang:masterfrom
rainers:bumpMallocFree
Draft

rainers wants to merge 3 commits into
dlang:masterfrom
rainers:bumpMallocFree

Conversation

@rainers

@rainers rainers commented Sep 25, 2026

Copy link
Copy Markdown
Member

For my usual testcase (all phobos unittests compiled with -o-), this reduces compilation time by about 9% (26.8 s -> 24.6 s) and reduces process memory by about 2.5 % (12212 MB -> 11943 MB).

Not sure if that's worth having to pass allocation sizes to mem.xfree and mem.xrealloc.

Let's see what the perf runner reports...

@rainers
rainers marked this pull request as draft September 25, 2026 19:47
@github-actions

github-actions Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

DMD perf check

Metric Base PR Δ
compile hello.d (instr) 203.6 M 204.6 M +0.498%
compile hello.d -O -release (instr) 221.2 M 222.2 M +0.469%
dmd binary size (stripped) 8.17 MB 8.18 MB +0.14%
peak RSS (compile Phobos) 610.2 MB 596.0 MB -2.32%
peak RSS (compile vibe.d) 1880 MB 1833 MB -2.48%
page faults (compile Phobos) 151,717 148,639 -2.03%
page faults (compile vibe.d) 470,239 458,873 -2.42%
Breakdown — compile hello.d
Phase (wall, self time) Base PR Δ
parse 17.8 ms 19.3 ms +8.78%
sema_other 11.7 ms 12.0 ms +2.36%
sema1 7.4 ms 7.1 ms -3.57%
sema3 3.6 ms 3.7 ms +4.45%
codegen 1.5 ms 1.5 ms +3.19%
All measurements
Metric Base PR Δ
compile hello.d (instr) 203.6 M 204.6 M +0.498%
compile hello.d -O -release (instr) 221.2 M 222.2 M +0.469%
compile Phobos (instr) 4,692.6 M 4,694.9 M +0.047%
compile Phobos codegen (instr) 1,417.1 M 1,418.5 M +0.099%
compile vibe.d (instr) 13,560.5 M 13,560.3 M -0.002%
dmd binary size (stripped) 8.17 MB 8.18 MB +0.14%
hello binary size (stripped) 0.72 MB 0.72 MB 0.00%
peak RSS (compile hello.d) 44.37 MB 43.92 MB -1.02%
peak RSS (compile Phobos) 610.2 MB 596.0 MB -2.32%
peak RSS (compile vibe.d) 1880 MB 1833 MB -2.48%
page faults (compile hello.d) 8,730 8,607 -1.41%
page faults (compile Phobos) 151,717 148,639 -2.03%
page faults (compile vibe.d) 470,239 458,873 -2.42%
compile dmd itself (wall) 7.7 s 7.7 s +0.44%
compile hello.d (wall) 41.9 ms 43.7 ms +4.24%
compile Phobos (wall) 916 ms 908 ms -0.90%

c01a0b2 vs merge-base f302b81 · about these metrics

@rainers
rainers force-pushed the bumpMallocFree branch 2 times, most recently from a152334 to e038f21 Compare September 26, 2026 07:54
Comment on lines +353 to +354
enum pureBumpMalloc = cast(void* function(size_t) pure nothrow)&bumpMalloc;
enum pureBumpFree = cast(void function(void*p, size_t) pure nothrow)&bumpFree;

@ibuclaw ibuclaw Sep 27, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could also fake it with pragma(mangle), which has support on older compilers.

extern (C) private pure @system @nogc nothrow

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, that seems to work across all versions. Updated.

@rainers rainers Sep 27, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LDC is not happy with this change: Function type does not match previously declared function with the same mangled name. Restored.

@nordlow

nordlow commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Cherry-picking this on master gives merge conflicts.

Update: Ahh, merge works. Nevermind this.

@dkorpel

dkorpel commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

Does this supersede #23914 ?

Not sure if that's worth having to pass allocation sizes to mem.xfree and mem.xrealloc.

I'd say definitely yes!

Comment on lines +272 to +283
enum smallAlignmentShift = 4;
enum smallAlignment = 1 << smallAlignmentShift;
enum maxSmallSize = 1024;
__gshared void*[maxSmallSize >> smallAlignmentShift] firstSmallFree;

enum largeAlignmentShift = 8;
enum largeAlignment = 1 << largeAlignmentShift;
enum maxLargeSize = 64 * 1024;
__gshared void*[maxLargeSize >> largeAlignmentShift] firstLargeFree;

enum hugeAlignment = 4096;
__gshared void* firstHugeFree;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this bucket strategy tuned for dmd?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this bucket strategy tuned for dmd?

Not really, just my first guess. I suspect allocation sizes are mostly rather small, but I can add some statistics on bucket usage.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's a summary of the bin usage of my phobos unittest benchmark:

Size range Mallocs Frees Approx. live memory Interpretation
0x01–0x10 8,587,199 3,549,229 ~50 MB Very high count
0x11–0x20 11,973,412 188,068 ~377 MB Huge count + memory
0x21–0x30 535,439 84,989 ~21 MB Moderate
0x31–0x40 2,076,679 17,630 ~131 MB High count + memory
0x41–0x50 7,573,155 36,854 ~452 MB Huge count + memory
0x51–0x60 108,464 5,100 ~6 MB Low impact
0x61–0x100 ~1k–26k/bucket ~0.5k–11k/bucket <10 MB each Low impact
0x101–0x300 ~700–6,000/bucket ~400–1,100/bucket <1 MB each Negligible individually
0x301–0x3000 hundreds–thousands tens–thousands <1 MB/bucket Low
0x3001–0xffff tens–thousands generally similar Generally small Low
>= 0x10000 89 57 ~47 MB net reported Few allocations, but expensive

@rainers

rainers commented Sep 29, 2026

Copy link
Copy Markdown
Member Author

Does this supersede #23914 ?

No, it replaces the C malloc calls by using the memory of the bump allocator, that can benefit additionally from #23914 when using larger pages. The measurements in #23914 (comment) were made on top of this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants