regalloc2 makes too many memory allocations
还没有人认领这个 Issue。
评估
- 难度
- 5/5
- 预计耗时
- 一周以上
- 新手友好度
- 35/100
- Issue 类型
- 重构
- 描述清晰度
- 基本清楚
- 活跃度
- 停滞
- 技术栈
- rust
- 领域
- compilers, performance
调研方向
从已命名的热点开始:尝试分析 try_to_allocate_bundle_to_reg、merge_bundles、insert_use_into_liverange、add_liverange_to_vreg、create_pregs_and_vregs 和 Env::new。检查 Env 以及所列 SmallVec、HashSet、BTreeMap 和 Vec 字段是如何创建和复用的,然后评估使用 cranelift-entity 和 cranelift-bforest 的 Context 设计。完成的标准是减少重复分配、保持分配器行为不变,并处理与 #62 的关系。
由索引模型根据 Issue 内容生成。
描述
I used heaptrack to analyze the memory allocation patterns of my compiler which uses regalloc2. I used a large benchmark (LLVM library) which has 1257955 basic blocks in 104913 functions. Out of a total of 46780667 allocations, 46779011 of them come from regalloc2 and only 1656 come from other parts of the compiler.
My compiler uses a similar structure [^1] to Cranelift where a Context structure allows memory allocations to be reused across compilation units. Specifically, this allows various Vecs and HashMaps to grow to a sufficient size only once while being reused many times for compiling multiple functions.
[^1]: In fact I am using the cranelift-entity crate directly, it's very well written.
regalloc2 unfortunately doesn't follow this design:
- A fresh
Envstructure is allocated and freed for each function. No memory allocations are preserved. - Heavy use of temporary
SmallVecs andHashSets. Heaptrack reports that 19865290 allocations (42% of the total) are "temporary". These are allocations which are immediately followed by a free, with no other allocations in between. - Heavy use of
BTreeMapwhich needs to allocate many nodes separately and cannot reuse memory unlikeHashMapandVec.
Heaptrack results
Here are the major allocation hotspots shown by heaptrack:
In try_to_allocate_bundle_to_reg:
- 16158324 temporary allocations from the
FxHashSet. - 9677435 allocations from inserting liveranges into
PRegData::allocations(LiveRangeSetbacked by aBTreeMap).
In merge_bundles:
- 4478881 allocations from pushing a
VRegtoSpillSet::vregs(SmallVec). - 1895443 allocations from appending
LiveRangeListEntrys toLiveBundle::ranges(SmallVec).
In insert_use_into_liverange:
- 2578957 allocations from pushing a
UsetoLiveRange::uses(SmallVec).
In add_liverange_to_vreg:
- 1432853 allocations from pushing a
LiveRangeListEntrytoVRegData::ranges(SmallVec).
In create_pregs_and_vregs:
- 948582 allocations from pushing to
Env::vregsandEnv::allocsandEnv::inst_alloc_offsets. (Vec)
In Env::new:
- 1154043 allocations from initializing the various
Vecs withVec::with_capacity.
Performance impact
Benchmarking shows that approximately 10% of the time is spent in memory allocation functions (malloc, realloc, free). Additionally, another 10% of the time is spent in memcpy/memmove which could be due to vector reallocation.
Compiling with multiple threads can cause additional contention on the global allocator. This was noticed on musl targets where the global allocator doesn't have thread-local caches: compiler performance on 6 threads (on a 6-core machine) was reduced to that of a single thread whereas other allocators allow almost-perfect performance scaling.
Proposed solution
I believe the best way to improve regalloc2 would be to use a design similar to Cranelift with a Context structure that can preserve memory allocation across multiple invocations of the register allocator.
- Temporary
SmallVecs andHashSets should be replaced with a single instance inContext. - The many
BTreeMaps should be replaced withcranelift-bforestwhich maintains a pool of nodes that can be reused. - The many
SmallVecs should be replaced withEntityListfromcranelift-entityand aListPoolinContext.
Since this would require a dependency on the cranelift-entity and cranelift-bforest crates, this is also a good opportunity to resolve #62 and switch to using proper indexed types internally.
- 主要语言
- Rust
- 星标
- 266
- 派生
- 54
- PR 合并指标
- 30 天内没有已合并 PR
贡献指南
这个仓库没有索引到贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
bytecodealliance/regalloc2 的其他 Issue
-
难度 4/5 3-5 天 新手友好度 48/100
bytecodealliance/regalloc2#265 · 9 条评论 ·
-
难度 5/5 一周以上 新手友好度 25/100
bytecodealliance/regalloc2#247 · 3 条评论 ·
-
难度 4/5 3-5 天 新手友好度 45/100
bytecodealliance/regalloc2#222 · 4 条评论 ·
-
难度 5/5 一周以上 新手友好度 25/100
bytecodealliance/regalloc2#206 · 2 条评论 ·
-
难度 3/5 1-2 天 新手友好度 35/100
bytecodealliance/regalloc2#194 · 7 条评论 ·
查看 bytecodealliance/regalloc2 的全部 Issue
相似的 Issue
-
难度 2/5 1-3 小时 新手友好度 75/100
TheLarkInn/aipm#2413 ·
-
documentation
难度 1/5 1 小时以内 新手友好度 90/100
alexgorbatchev/simple-ptt#15 ·
-
tooling
难度 2/5 1-3 小时 新手友好度 75/100
-
todo:ticket
难度 2/5 1-3 小时 新手友好度 70/100
-
难度 2/5 1-3 小时 新手友好度 75/100
taikoxyz/taiko-mono#22168 · 1 条评论 ·