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

feat: optimize brillig ToRadix for common radices #7365

Draft
wants to merge 17 commits into
base: master
Choose a base branch
from

Conversation

TomAFrench
Copy link
Member

Description

Problem*

Resolves

Summary*

For a number of radices (notably 2 and 256) we can avoid the usage of BigUint and just decompose the field into bytes and do a few bitwise operations. I'd expect this to significantly outperform the fully general implementation.

Additional Context

Documentation*

Check one:

  • No documentation needed.
  • Documentation included in this PR.
  • [For Experimental Features] Documentation to be submitted in a separate PR.

PR Checklist*

  • I have tested the changes locally.
  • I have formatted the changes with Prettier and/or cargo fmt on default settings.

@TomAFrench TomAFrench marked this pull request as ready for review February 13, 2025 00:35
@TomAFrench TomAFrench requested a review from a team February 13, 2025 00:35
@TomAFrench TomAFrench marked this pull request as draft February 13, 2025 01:09
@TomAFrench
Copy link
Member Author

I'd like to add some benchmarks for this to check performance.

TomAFrench and others added 3 commits February 13, 2025 18:48
* master:
  chore: avoid u128s in brillig memory (#7363)
  chore: update docs about integer overflows (#7370)
  fix!: Only decrement the counter of an array if its address has not changed (#7297)
  fix: let LSP read `noirfmt.toml` for formatting files (#7355)
  chore: deprecate keccak256 (#7361)
@TomAFrench
Copy link
Member Author

This cuts the time to do a field decomposition from 1.9588 µs to 752.21 ns

@TomAFrench TomAFrench marked this pull request as ready for review February 14, 2025 19:02
@TomAFrench TomAFrench added the bench-show Display benchmark results on PR label Feb 14, 2025
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Compilation Time

Benchmark suite Current: 80f6a01 Previous: 4aba428 Ratio
sha256_regression 0.956 s 0.947 s 1.01
regression_4709 0.697 s 0.681 s 1.02
ram_blowup_regression 21.3 s 21 s 1.01
global_var_regression_entry_points 0.514 s 0.515 s 1.00
private-kernel-inner 2.05 s 2.05 s 1
private-kernel-reset 6.432 s 6.442 s 1.00
private-kernel-tail 1.022 s 1.056 s 0.97
rollup-base-private 8.966 s 8.476 s 1.06
rollup-base-public 5.22 s 5.012 s 1.04
rollup-block-root-empty 0.985 s 0.959 s 1.03
rollup-block-root-single-tx 93.2 s 94.1 s 0.99
rollup-block-root 90.5 s 95.7 s 0.95
rollup-merge 0.943 s 0.942 s 1.00
rollup-root 1.518 s 1.48 s 1.03

This comment was automatically generated by workflow using github-action-benchmark.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Execution Time

Benchmark suite Current: 80f6a01 Previous: 4aba428 Ratio
private-kernel-inner 0.07 s 0.07 s 1
private-kernel-reset 0.296 s 0.294 s 1.01
private-kernel-tail 0.017 s 0.017 s 1
rollup-base-private 0.432 s 0.43 s 1.00
rollup-base-public 0.182 s 0.183 s 0.99
rollup-block-root 35.5 s 34.9 s 1.02
rollup-merge 0.006 s 0.007 s 0.86
rollup-root 0.039 s 0.038 s 1.03

This comment was automatically generated by workflow using github-action-benchmark.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Compilation Memory

Benchmark suite Current: 80f6a01 Previous: 4aba428 Ratio
private-kernel-inner 285.64 MB 285.59 MB 1.00
private-kernel-reset 597.57 MB 597.57 MB 1
private-kernel-tail 209.2 MB 209.2 MB 1
rollup-base-private 955.94 MB 955.94 MB 1
rollup-base-public 828.6 MB 828.64 MB 1.00
rollup-block-root-empty 338.68 MB 338.68 MB 1
rollup-block-root-single-tx 6880 MB 6880 MB 1
rollup-block-root 6880 MB 6880 MB 1
rollup-merge 337.11 MB 337.11 MB 1
rollup-root 384.8 MB 384.79 MB 1.00

This comment was automatically generated by workflow using github-action-benchmark.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Execution Memory

Benchmark suite Current: 80f6a01 Previous: 4aba428 Ratio
private-kernel-inner 224.77 MB 224.77 MB 1
private-kernel-reset 259.37 MB 259.37 MB 1
private-kernel-tail 194.78 MB 194.78 MB 1
rollup-base-private 441.42 MB 441.42 MB 1
rollup-base-public 382.59 MB 382.59 MB 1
rollup-block-root 1420 MB 1420 MB 1
rollup-merge 321.52 MB 321.52 MB 1
rollup-root 328.9 MB 328.9 MB 1

This comment was automatically generated by workflow using github-action-benchmark.

Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Test Suite Duration

Benchmark suite Current: 80f6a01 Previous: 4aba428 Ratio
AztecProtocol_aztec-packages_noir-projects_aztec-nr 38 s 39 s 0.97
AztecProtocol_aztec-packages_noir-projects_noir-contracts 79 s 77 s 1.03
AztecProtocol_aztec-packages_noir-projects_noir-protocol-circuits_crates_blob 63 s 63 s 1
AztecProtocol_aztec-packages_noir-projects_noir-protocol-circuits_crates_private-kernel-lib 164 s 162 s 1.01
AztecProtocol_aztec-packages_noir-projects_noir-protocol-circuits_crates_reset-kernel-lib 11 s 11 s 1
AztecProtocol_aztec-packages_noir-projects_noir-protocol-circuits_crates_rollup-lib 165 s 163 s 1.01
AztecProtocol_aztec-packages_noir-projects_noir-protocol-circuits_crates_types 55 s 54 s 1.02
noir-lang_noir-bignum_ 337 s 357 s 0.94
noir-lang_noir_bigcurve_ 272 s 290 s 0.94
noir-lang_noir_json_parser_ 10 s 9 s 1.11

This comment was automatically generated by workflow using github-action-benchmark.


use std::time::Duration;

fn byte_decomposition(c: &mut Criterion) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Are these benchmarks meant to be temporary or permanent?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think we can have them be permanent.

@TomAFrench TomAFrench requested a review from a team February 21, 2025 20:14
@TomAFrench TomAFrench enabled auto-merge February 21, 2025 20:36
// TODO: raise an error if we cannot fit `input` into `num_limbs`.
match radix {
256 => {
let bytes_le = input.to_be_bytes().into_iter().rev();
Copy link
Contributor

Choose a reason for hiding this comment

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

We should have to_le_bytes() now.

Copy link
Contributor

Choose a reason for hiding this comment

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

Alternatively instead of .take(num_limbs) followed by .rev() you could try:

let bytes_be = input.to_be_bytes();
let lowest_bytes_be = bytes_be.skip(num_limbs - bytes_be.len());

@TomAFrench TomAFrench marked this pull request as draft February 25, 2025 11:00
auto-merge was automatically disabled February 25, 2025 11:00

Pull request was converted to draft

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bench-show Display benchmark results on PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants