添加 Heap dealloc free-list scan benchmark - #55
Merged
jiegec merged 4 commits intoJul 5, 2026
Conversation
added 2 commits
July 4, 2026 22:01
Add a Criterion benchmark that measures Heap::dealloc free-list scan cost across multiple scales (100–10000 buddy pairs). Constructs a fragmented workload where free_list[class_6] accumulates freed blocks, then deallocates their lower-half buddies — each triggering a linear scan of the intrusive linked list to find its buddy. Key design: - Uses raw Heap (not LockedHeap) to avoid spinlock noise - Paired-buddy strategy with XOR-based pairing and class-7 isolation - iter_batched with fresh heap state per iteration - Multiple sizes (100/500/1k/2k/5k/10k pairs) to show O(N²) degradation Results demonstrate the scan cost grows quadratically as the free list lengthens: ~25µs at 100 pairs → ~1.7s at 10000 pairs. Also fix: replace deprecated criterion::black_box with std::hint::black_box in both bench files. Add .omo/ and core to .gitignore.
5000 pairs already demonstrates O(N²) scan cost clearly (217ms vs 24µs at 100 pairs). 10000 takes ~250s with default sample size — too heavy for a quick cargo bench run.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds a new Criterion benchmark to reproduce and measure buddy_system_allocator::Heap::dealloc’s free-list buddy-lookup scan cost under a deliberately fragmented workload, enabling future optimization work to be evaluated against a stable in-repo scenario.
Changes:
- Register a new
heap_dealloc_scanbenchmark target inCargo.toml. - Add
benches/heap_dealloc_scan.rs, which constructs a longfree_list[6]and measuresdeallocscaling across multiple pair counts. - Minor benchmark-related cleanups to the existing
memory_allocator_benchmarkand.gitignore.
Reviewed changes
Copilot reviewed 3 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| Cargo.toml | Adds the new heap_dealloc_scan Criterion bench target. |
| benches/memory_allocator_benchmark.rs | Updates benchmark harness usage (rand API / black_box / ctor init details). |
| benches/heap_dealloc_scan.rs | Introduces the new benchmark that stresses Heap::dealloc free-list scanning behavior. |
| .gitignore | Adds ignores for additional local artifacts. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Member
|
benchmark 是可以加,不过本项目不考虑对分配算法进行优化,主要还是教科书上算法的直接实现,用于教学目的。 |
Contributor
Author
|
明白了,感谢review,那这个pr只加benchmark可以吗,优化部分的工作我们自己fork下来做 |
jiegec
reviewed
Jul 5, 2026
jiegec
reviewed
Jul 5, 2026
Contributor
Author
|
修好了,请review |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
概要
这个 PR 为
Heap添加了一个 Criterion benchmark,用来构造一种碎片化场景:在释放内存时,dealloc需要在较长的 free list 中查找 buddy block。这个 PR 只添加 benchmark,不修改 allocator 的任何行为。
背景
我在把
buddy_system_allocator::Heap用作内核堆分配器时,遇到过一种 workload:大量重复的分配和释放会让某些 size class 的 free list 变长。当前
Heap::dealloc的逻辑会先计算 buddy 地址,但随后仍然需要遍历free_list[current_class],确认对应的 buddy block 是否处于空闲状态。在碎片化比较明显的场景下,释放路径的开销会受到 free list 长度影响。这个 benchmark 的目的,是在本仓库内提供一个尽量小的可复现场景,方便后续评估相关优化。
本地测试结果
我在本地运行:
得到结果如下:
较大的 case 是有意保留的压力场景,主要用于观察当 benchmark 构造出较长 free list 后,释放路径成本随之增长的趋势。可以看到性能的退化还是较为明显的,并且在我们内核的实践上,发现这样程度的退化对性能的影响较为显著
benchmark 做了什么
这个 benchmark 大致会:
初始化一个独立的
Heap;分配大量相同大小的块;
按特定模式释放其中一部分块,让某个 size class 的 free list 变长;
再释放另一部分块,触发
dealloc中的 buddy lookup 路径。benchmark 直接使用
Heap,没有使用LockedHeap,这样可以尽量排除锁开销,更专注于 allocator 本身的行为。后续想法
如果这个 benchmark 被认为有价值,我后续想继续探索一个可选的 metadata-backed heap 实现。
大致思路是参考页分配器中常见的做法:不要只把 free list 当作唯一的状态来源,而是为被管理的 block 维护显式 metadata,记录 block 的状态和 order。这样在
dealloc时,可以通过 buddy 地址直接判断 buddy block 是否空闲,而不必线性扫描当前 order 的 free list。后续可能的实现方向:
默认保持现有
Heap/LockedHeap行为不变;新增一个可选 feature,或者新增一个 metadata-backed heap 类型;
显式记录 block 的状态和 order;
使用 per-order free area,并支持 O(1) unlink;
尽量复用现有 heap 测试,验证新实现和现有行为的一致性;
用这个 benchmark 对比优化前后的表现。
我还不确定这个方向是否适合本项目,所以希望先通过这个 benchmark PR 收集一下维护者的意见,再决定是否继续实现。