Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[perf] Use Vec instead of BTreeMap in tree_from_memory #1338

Merged
merged 15 commits into from
Feb 5, 2025

Conversation

Golovanov399
Copy link
Contributor

@Golovanov399 Golovanov399 commented Feb 4, 2025

Metric: tracegen
Before: 10,901.18 ms
After: 10,131.55 ms
Percentage gain: -7.1%

Workflow: https://github.com/axiom-crypto/openvm-reth-benchmark/actions/runs/13160394734


This resolves INT-3236.

Quote from the ticket.
Our current AddressMap.items() returns something sorted by address (more specifically by (address_space, pointer) lexicographically), therefore no need to push it into a BTreeMap, we can push it into Vec and then modify the recursion a little bit.
We can also save on creating the "all-zero" nodes by building them once and then taking the corresponding node every time we need such node for some height. This should in theory always be strictly better, but this is worse now [...].
End of quote.

I also tried to calculate the capacity once and then reserve the exact capacity needed once instead of Vec::new() and .push() every time, but this was slightly slower or at least the same.

This comment has been minimized.

This comment has been minimized.

This comment has been minimized.

This comment has been minimized.

@Golovanov399
Copy link
Contributor Author

@zlangley I couldn't think of a simple way to avoid collecting items

This comment has been minimized.

crates/vm/src/system/memory/tree/mod.rs Outdated Show resolved Hide resolved
crates/vm/src/system/memory/tree/mod.rs Outdated Show resolved Hide resolved
for ((address_space, pointer), value) in memory.items() {
if pointer as usize / CHUNK >= (1 << memory_dimensions.address_height) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Doesn't this mean something bad happened at run-time and the proof will fail? Can't we remove this and just leave the assert below?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This will happen when memory size is not divisible by page size, which, if both of these are powers of two, is equivalent to memory size being less than page size. We can assert that this is not the case and modify the tests correspondingly, in principle

// representing the entire memory tree.
let mut memory_partition = BTreeMap::new();
let mut memory_partition: Vec<(u64, [F; CHUNK])> = Vec::new();
for ((address_space, pointer), value) in memory.items() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Note: It's a bit unfortunate that MemoryImage is (address_space, pointer) -> F rather than (address_space, label) -> [F; 8]. I feel like this means we have to do a lot of extra work here and at the end of a segment to convert it into both forms.

Copy link
Contributor

@jonathanpwang jonathanpwang left a comment

Choose a reason for hiding this comment

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

LGTM, added some future ideas

This comment has been minimized.

This comment has been minimized.

@Golovanov399 Golovanov399 force-pushed the perf/offline-memory-tree-from-memory branch from 4345385 to 0b41e45 Compare February 5, 2025 14:50
@Golovanov399 Golovanov399 force-pushed the perf/offline-memory-tree-from-memory branch from 0b41e45 to 090d703 Compare February 5, 2025 14:58

This comment has been minimized.

This comment has been minimized.

Copy link

github-actions bot commented Feb 5, 2025

group app.proof_time_ms app.cycles app.cells_used leaf.proof_time_ms leaf.cycles leaf.cells_used
verify_fibair (-22 [-1.4%]) 1,522 187,385 9,765,005 - - -
fibonacci_program (+17 [+0.3%]) 4,953 1,500,095 51,485,080 - - -
regex_program 14,371 1,914,103 165,455,373 - - -
ecrecover_program (-9 [-0.4%]) 2,489 284,567 15,055,723 - - -

Commit: 1aa0c56

Benchmark Workflow

}
debug_assert!(memory_partition.is_sorted_by_key(|(addr, _)| addr));
let memory_items = memory
.items()
Copy link
Contributor

Choose a reason for hiding this comment

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

change items() to use par_iter now!

Copy link
Contributor

Choose a reason for hiding this comment

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

actually maybe it's too trivial, let's try separately of this PR

@jonathanpwang jonathanpwang merged commit 271038b into main Feb 5, 2025
22 checks passed
@jonathanpwang jonathanpwang deleted the perf/offline-memory-tree-from-memory branch February 5, 2025 20:22
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.

3 participants