regalloc2 makes too many memory allocations
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 5/5
- Thời gian dự kiến
- Hơn một tuần
- Mức phù hợp với người mới
- 35/100
- Loại issue
- Tái cấu trúc
- Độ rõ ràng
- Khá rõ ràng
- Mức độ hoạt động
- Đình trệ
- Công nghệ
- rust
- Lĩnh vực
- compilers, performance
Hướng nghiên cứu
Bắt đầu với các hotspot đã nêu: xem xét try_to_allocate_bundle_to_reg, merge_bundles, insert_use_into_liverange, add_liverange_to_vreg, create_pregs_and_vregs và Env::new. Rà soát cách Env và các trường SmallVec, HashSet, BTreeMap và Vec được liệt kê được tạo và tái sử dụng, sau đó đánh giá một thiết kế Context sử dụng cranelift-entity và cranelift-bforest. Công việc được xem là hoàn tất khi giảm được các lần cấp phát lặp lại, vẫn giữ nguyên hành vi của bộ cấp phát và xử lý mối quan hệ với #62.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
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.
- Ngôn ngữ chính
- Rust
- Star
- 266
- Fork
- 54
- Chỉ số merge pull request
- Không có pull request nào được merge trong 30 ngày
Hướng dẫn đóng góp
Chưa lập chỉ mục được hướng dẫn đóng góp cho kho mã nguồn này
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của bytecodealliance/regalloc2
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 48/100
bytecodealliance/regalloc2#265 · 8 bình luận ·
-
Modeling subregister aliasing Đang mở
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 25/100
bytecodealliance/regalloc2#247 · 3 bình luận ·
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 45/100
bytecodealliance/regalloc2#222 · 4 bình luận ·
-
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 25/100
bytecodealliance/regalloc2#206 · 2 bình luận ·
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 35/100
bytecodealliance/regalloc2#194 · 7 bình luận ·
Tất cả issue của bytecodealliance/regalloc2
Issue tương tự
-
Replayed reasoning items send "content": null, which the Responses API schema does not permit Đang mởbug CLI custom-model
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
rust-bitcoin/rust-bitcoin#6930 · 1 bình luận ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
fulcrumgenomics/ferro-hgvs#2251 ·
-
Missing examples for `Allocator` Đang mởA-allocators A-docs C-enhancement T-libs
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100