Skip to content

Consider use unchecked math #11

Open

Description

@cmpute

It's worth testing unchecked math (stablized in 1.85, rust-lang/rust#85122) for accelerating primitive operations.

Activity

  1. cmpute commented on Jun 9, 2026

    @cmpute
    OwnerAuthor

    Initial investigations:

    Benchmark Comparison: Normal vs Unchecked Operators
    
      Test modulus: 2^31 - 1 (Mersenne prime, fits all widths)
    
      FixedMersenne32 (u32)
    
      ┌───────────┬───────────┬───────────┬───────────────┐
      │ Operation │  Before   │   After   │     Delta     │
      ├───────────┼───────────┼───────────┼───────────────┤
      │ transform │ 141.50 ns │ 136.50 ns │ -3.5%         │
      ├───────────┼───────────┼───────────┼───────────────┤
      │ add       │ 22.45 ns  │ 22.39 ns  │ -0.3%         │
      ├───────────┼───────────┼───────────┼───────────────┤
      │ mul       │ 257.89 ns │ 252.53 ns │ -2.1%         │
      ├───────────┼───────────┼───────────┼───────────────┤
      │ sqr       │ 233.76 ns │ 236.16 ns │ +1.0% (noise) │
      ├───────────┼───────────┼───────────┼───────────────┤
      │ inv       │ 41.40 µs  │ 40.80 µs  │ -1.4%         │
      └───────────┴───────────┴───────────┴───────────────┘
    
      FixedMersenne64 (u64)
    
      ┌───────────┬───────────┬───────────┬────────────────┐
      │ Operation │  Before   │   After   │     Delta      │
      ├───────────┼───────────┼───────────┼────────────────┤
      │ transform │ 156.28 ns │ 165.50 ns │ +5.9%* (noisy) │
      ├───────────┼───────────┼───────────┼────────────────┤
      │ add       │ 50.25 ns  │ 50.27 ns  │ ~0%            │
      ├───────────┼───────────┼───────────┼────────────────┤
      │ mul       │ 276.10 ns │ 271.03 ns │ -1.8%          │
      ├───────────┼───────────┼───────────┼────────────────┤
      │ sqr       │ 238.11 ns │ 234.12 ns │ -1.7%          │
      ├───────────┼───────────┼───────────┼────────────────┤
      │ inv       │ 40.99 µs  │ 40.52 µs  │ -1.1%          │
      └───────────┴───────────┴───────────┴────────────────┘
    
      FixedMersenne (u128)
    
      ┌───────────┬───────────┬───────────┬───────────────┐
      │ Operation │  Before   │   After   │     Delta     │
      ├───────────┼───────────┼───────────┼───────────────┤
      │ transform │ 172.79 ns │ 174.78 ns │ +1.2% (noise) │
      ├───────────┼───────────┼───────────┼───────────────┤
      │ add       │ 288.92 ns │ 287.77 ns │ -0.4%         │
      ├───────────┼───────────┼───────────┼───────────────┤
      │ mul       │ 513.11 ns │ 504.08 ns │ -1.8%         │
      ├───────────┼───────────┼───────────┼───────────────┤
      │ sqr       │ 457.17 ns │ 447.93 ns │ -2.0%         │
      ├───────────┼───────────┼───────────┼───────────────┤
      │ inv       │ 40.69 µs  │ 40.88 µs  │ +0.5%         │
      └───────────┴───────────┴───────────┴───────────────┘
    
      ---
      Summary: The main wins are in mul (1.8–2.1% faster across all widths) and sqr (1.7–2.0% on 64/128-bit). The add/sub/neg operations saw negligible changes
      since they're dominated by memory/call overhead. inv is unchanged since it uses extended GCD rather than the reduction loop. The performance gain comes
      from removing the overflow checks in the hot reduction loops — the compiler previously emitted conditional traps for each +, -, and * even though the
      algorithm guarantees they can't overflow.
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions