Skip to content

Commit

Permalink
Improve widening mul operations' performance on wasm (#828)
Browse files Browse the repository at this point in the history
Co-authored-by: Marcin <[email protected]>
  • Loading branch information
sarah and mmagician authored Jun 19, 2024
1 parent 7bd57f5 commit 8183072
Showing 1 changed file with 28 additions and 5 deletions.
33 changes: 28 additions & 5 deletions ff/src/biginteger/arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,34 @@ pub fn sbb_for_sub_with_borrow(a: &mut u64, b: u64, borrow: u8) -> u8 {
}
}

#[inline(always)]
#[doc(hidden)]
pub const fn widening_mul(a: u64, b: u64) -> u128 {
#[cfg(not(target_family = "wasm"))]
{
a as u128 * b as u128
}
#[cfg(target_family = "wasm")]
{
let a_lo = a as u32 as u64;
let a_hi = a >> 32;
let b_lo = b as u32 as u64;
let b_hi = b >> 32;

let lolo = (a_lo * b_lo) as u128;
let lohi = ((a_lo * b_hi) as u128) << 32;
let hilo = ((a_hi * b_lo) as u128) << 32;
let hihi = ((a_hi * b_hi) as u128) << 64;
(lolo | hihi) + (lohi + hilo)
}
}

/// Calculate a + b * c, returning the lower 64 bits of the result and setting
/// `carry` to the upper 64 bits.
#[inline(always)]
#[doc(hidden)]
pub fn mac(a: u64, b: u64, c: u64, carry: &mut u64) -> u64 {
let tmp = (a as u128) + (b as u128 * c as u128);
let tmp = (a as u128) + widening_mul(b, c);
*carry = (tmp >> 64) as u64;
tmp as u64
}
Expand All @@ -97,21 +119,22 @@ pub fn mac(a: u64, b: u64, c: u64, carry: &mut u64) -> u64 {
#[inline(always)]
#[doc(hidden)]
pub fn mac_discard(a: u64, b: u64, c: u64, carry: &mut u64) {
let tmp = (a as u128) + (b as u128 * c as u128);
let tmp = (a as u128) + widening_mul(b, c);
*carry = (tmp >> 64) as u64;
}

macro_rules! mac_with_carry {
($a:expr, $b:expr, $c:expr, &mut $carry:expr$(,)?) => {{
let tmp = ($a as u128) + ($b as u128 * $c as u128) + ($carry as u128);
let tmp =
($a as u128) + $crate::biginteger::arithmetic::widening_mul($b, $c) + ($carry as u128);
$carry = (tmp >> 64) as u64;
tmp as u64
}};
}

macro_rules! mac {
($a:expr, $b:expr, $c:expr, &mut $carry:expr$(,)?) => {{
let tmp = ($a as u128) + ($b as u128 * $c as u128);
let tmp = ($a as u128) + $crate::biginteger::arithmetic::widening_mul($b, $c);
$carry = (tmp >> 64) as u64;
tmp as u64
}};
Expand All @@ -122,7 +145,7 @@ macro_rules! mac {
#[inline(always)]
#[doc(hidden)]
pub fn mac_with_carry(a: u64, b: u64, c: u64, carry: &mut u64) -> u64 {
let tmp = (a as u128) + (b as u128 * c as u128) + (*carry as u128);
let tmp = (a as u128) + widening_mul(b, c) + (*carry as u128);
*carry = (tmp >> 64) as u64;
tmp as u64
}
Expand Down

0 comments on commit 8183072

Please sign in to comment.