-
Notifications
You must be signed in to change notification settings - Fork 76
Implement Karatsuba multiplication for Uint and BoxedUint #649
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
Conversation
Signed-off-by: Andrew Whitehead <[email protected]>
Signed-off-by: Andrew Whitehead <[email protected]>
Signed-off-by: Andrew Whitehead <[email protected]>
|
@dignifiedquire I probably could have copied some of the more extensive documentation from your PR, maybe there's something there you'd like to add. |
| @@ -0,0 +1,414 @@ | |||
| //! Karatsuba multiplication | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small nit but I'd probably suggest putting this under mul/karatsuba.rs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/uint/mul or src/mul?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
src/uint/mul
Signed-off-by: Andrew Whitehead <[email protected]>
src/uint/boxed/mul.rs
Outdated
| let size = self.nlimbs() + rhs.nlimbs(); | ||
| let overlap = self.nlimbs().min(rhs.nlimbs()); | ||
|
|
||
| if self.nlimbs().min(rhs.nlimbs()) >= 32 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where does 32 come from? Perhaps it could use a constant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's from benchmarking on this machine, only applying the reduction where it's likely to be faster.
src/uint/boxed/mul.rs
Outdated
| let mut limbs = vec![Limb::ZERO; self.nlimbs() * 2]; | ||
| let size = self.nlimbs() * 2; | ||
|
|
||
| if self.nlimbs() >= 64 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Likewise here, this could probably also use a constant (or short expression like KARATSUBA_MIN_LIMBS * 2 or thereabouts)
ed4e962 to
ba9763c
Compare
Signed-off-by: Andrew Whitehead <[email protected]>
ba9763c to
105edc7
Compare
Another PR to review, sorry...
This PR adds Karatsuba multiplication and squaring algorithms for both Uint and BoxedUint. The BoxedUint implementation is fairly flexible, and multiplication is supported for mixed operand sizes. The constants used may need tweaking, especially for 32 bit platforms to ensure the best implementation is chosen. On my 64-bit platform the numbers are currently:
(There is not a linear relationship in the improvements, although the relative timings did become more linear with the integer size)
The Uint implementation is more limited due to the strict typing, and is currently only implemented for
split_mulwith 16, 32, 64, or 128 limb arguments (U1024, U2048, U4096, U8192 on 64-bit) as well assquare_widewith 64 or 128 limb arguments.