mul and from optimizations
This commit is contained in:
parent
5d904b8585
commit
46bcf5e8b9
|
@ -1,3 +1,4 @@
|
|||
target
|
||||
.idea
|
||||
Cargo.lock
|
||||
Cargo.lock
|
||||
*.swp
|
||||
|
|
|
@ -101,3 +101,28 @@ fn u128_mul(b: &mut Bencher) {
|
|||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn u256_from_le(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let raw = black_box([
|
||||
1u8, 2, 3, 5, 7, 11, 13, 17,
|
||||
19, 23, 29, 31, 37, 41, 43, 47,
|
||||
53, 59, 61, 67, 71, 73, 79, 83,
|
||||
89, 97, 101, 103, 107, 109, 113, 127
|
||||
]);
|
||||
let _ = U256::from_little_endian(&raw[..]);
|
||||
});
|
||||
}
|
||||
|
||||
#[bench]
|
||||
fn u256_from_be(b: &mut Bencher) {
|
||||
b.iter(|| {
|
||||
let raw = black_box([
|
||||
1u8, 2, 3, 5, 7, 11, 13, 17,
|
||||
19, 23, 29, 31, 37, 41, 43, 47,
|
||||
53, 59, 61, 67, 71, 73, 79, 83,
|
||||
89, 97, 101, 103, 107, 109, 113, 127
|
||||
]);
|
||||
let _ = U256::from_big_endian(&raw[..]);
|
||||
});
|
||||
}
|
||||
|
|
63
src/uint.rs
63
src/uint.rs
|
@ -29,7 +29,7 @@
|
|||
//! implementations for even more speed, hidden behind the `x64_arithmetic`
|
||||
//! feature flag.
|
||||
|
||||
use core::str;
|
||||
use core::{str, mem};
|
||||
use core::ops::{Shr, Shl, BitAnd, BitOr, BitXor, Not, Div, Rem, Mul, Add, Sub};
|
||||
|
||||
use byteorder::{ByteOrder, BigEndian, LittleEndian};
|
||||
|
@ -392,16 +392,20 @@ macro_rules! uint_overflowing_mul_reg {
|
|||
let $name(ref you) = $other;
|
||||
let mut ret = [0u64; 2*$n_words];
|
||||
|
||||
for i in 0..$n_words {
|
||||
let mut i = 0;
|
||||
for _ in 0..$n_words {
|
||||
if you[i] == 0 {
|
||||
i += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut carry2 = 0u64;
|
||||
let (b_u, b_l) = split(you[i]);
|
||||
|
||||
for j in 0..$n_words {
|
||||
let mut j = 0;
|
||||
for _ in 0..$n_words {
|
||||
if me[j] == 0 && carry2 == 0 {
|
||||
j += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -422,17 +426,21 @@ macro_rules! uint_overflowing_mul_reg {
|
|||
|
||||
// Only single overflow possible there
|
||||
carry2 = (o1 | o2 | o3) as u64;
|
||||
j += 1;
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
|
||||
let mut res = [0u64; $n_words];
|
||||
let mut overflow = false;
|
||||
for i in 0..$n_words {
|
||||
res[i] = ret[i];
|
||||
}
|
||||
res.copy_from_slice(&ret[0..$n_words]);
|
||||
|
||||
for i in $n_words..2*$n_words {
|
||||
overflow |= ret[i] != 0;
|
||||
unsafe {
|
||||
let mut ret_ptr = ret.as_ptr().offset($n_words);
|
||||
for _ in $n_words..2*$n_words {
|
||||
overflow |= *ret_ptr != 0;
|
||||
ret_ptr = ret_ptr.offset(1);
|
||||
}
|
||||
}
|
||||
|
||||
($name(res), overflow)
|
||||
|
@ -809,11 +817,17 @@ macro_rules! construct_uint {
|
|||
assert!($n_words * 8 >= slice.len());
|
||||
|
||||
let mut ret = [0; $n_words];
|
||||
for i in 0..slice.len() {
|
||||
let rev = slice.len() - 1 - i;
|
||||
let pos = rev / 8;
|
||||
ret[pos] += (slice[i] as u64) << ((rev % 8) * 8);
|
||||
unsafe {
|
||||
let ret_u8: &mut [u8; $n_words * 8] = mem::transmute(&mut ret);
|
||||
let mut ret_ptr = ret_u8.as_mut_ptr();
|
||||
let mut slice_ptr = slice.as_ptr().offset(slice.len() as isize - 1);
|
||||
for _ in 0..slice.len() {
|
||||
*ret_ptr = *slice_ptr;
|
||||
ret_ptr = ret_ptr.offset(1);
|
||||
slice_ptr = slice_ptr.offset(-1);
|
||||
}
|
||||
}
|
||||
|
||||
$name(ret)
|
||||
}
|
||||
|
||||
|
@ -822,10 +836,11 @@ macro_rules! construct_uint {
|
|||
assert!($n_words * 8 >= slice.len());
|
||||
|
||||
let mut ret = [0; $n_words];
|
||||
for i in 0..slice.len() {
|
||||
let pos = i / 8;
|
||||
ret[pos] += (slice[i] as u64) << ((i % 8) * 8);
|
||||
unsafe {
|
||||
let ret_u8: &mut [u8; $n_words * 8] = mem::transmute(&mut ret);
|
||||
ret_u8[0..slice.len()].copy_from_slice(&slice);
|
||||
}
|
||||
|
||||
$name(ret)
|
||||
}
|
||||
}
|
||||
|
@ -2419,6 +2434,24 @@ mod tests {
|
|||
assert_eq!(&raw, &new_raw);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn slice_roundtrip_le2() {
|
||||
let raw = [
|
||||
2, 3, 5, 7, 11, 13, 17,
|
||||
19, 23, 29, 31, 37, 41, 43, 47,
|
||||
53, 59, 61, 67, 71, 73, 79, 83,
|
||||
89, 97, 101, 103, 107, 109, 113, 127
|
||||
];
|
||||
|
||||
let u256 = U256::from_little_endian(&raw[..]);
|
||||
|
||||
let mut new_raw = [0u8; 32];
|
||||
|
||||
u256.to_little_endian(&mut new_raw);
|
||||
|
||||
assert_eq!(&raw, &new_raw[..31]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fixed_arrays_roundtrip() {
|
||||
let raw: U256 = "7094875209347850239487502394881".into();
|
||||
|
|
Loading…
Reference in New Issue