An even better Owen scrambling hash.

This commit is contained in:
Nathan Vegdahl 2021-01-23 00:55:54 +09:00
parent c32281b04a
commit c48839d5f3
2 changed files with 60 additions and 17 deletions

View File

@ -66,10 +66,10 @@ pub fn sample_4d(sample_index: u32, dimension_set: u32, seed: u32) -> [f32; 4] {
fn lk_scramble(mut n: u32, scramble: u32) -> u32 { fn lk_scramble(mut n: u32, scramble: u32) -> u32 {
let scramble = hash(scramble); let scramble = hash(scramble);
n = n.wrapping_add(scramble);
n ^= n.wrapping_mul(0x3354734a);
n = n.wrapping_add(n << 2); n = n.wrapping_add(n << 2);
n ^= n.wrapping_mul(scramble & !1); n ^= n.wrapping_mul(0xfe9b5742);
n = n.wrapping_add(scramble);
n = n.wrapping_mul(scramble | 1);
n n
} }
@ -79,10 +79,10 @@ fn lk_scramble(mut n: u32, scramble: u32) -> u32 {
fn lk_scramble_int4(mut n: Int4, scramble: u32) -> Int4 { fn lk_scramble_int4(mut n: Int4, scramble: u32) -> Int4 {
let scramble = hash_int4([scramble; 4].into()); let scramble = hash_int4([scramble; 4].into());
n += scramble;
n ^= n * [0x3354734a; 4].into();
n += n << 2; n += n << 2;
n ^= n * (scramble & [!1; 4].into()); n ^= n * [0xfe9b5742; 4].into();
n += scramble;
n *= scramble | [1; 4].into();
n n
} }

View File

@ -145,6 +145,40 @@ pub(crate) mod sse {
} }
} }
impl std::ops::BitAnd for Int4 {
type Output = Int4;
#[inline(always)]
fn bitand(self, other: Self) -> Int4 {
Int4 {
v: unsafe { _mm_and_si128(self.v, other.v) },
}
}
}
impl std::ops::BitAndAssign for Int4 {
fn bitand_assign(&mut self, other: Self) {
*self = *self & other;
}
}
impl std::ops::BitOr for Int4 {
type Output = Int4;
#[inline(always)]
fn bitor(self, other: Self) -> Int4 {
Int4 {
v: unsafe { _mm_or_si128(self.v, other.v) },
}
}
}
impl std::ops::BitOrAssign for Int4 {
fn bitor_assign(&mut self, other: Self) {
*self = *self | other;
}
}
impl std::ops::BitXor for Int4 { impl std::ops::BitXor for Int4 {
type Output = Int4; type Output = Int4;
@ -163,17 +197,6 @@ pub(crate) mod sse {
} }
} }
impl std::ops::BitAnd for Int4 {
type Output = Int4;
#[inline(always)]
fn bitand(self, other: Self) -> Int4 {
Int4 {
v: unsafe { _mm_and_si128(self.v, other.v) },
}
}
}
impl std::ops::Shl<i32> for Int4 { impl std::ops::Shl<i32> for Int4 {
type Output = Int4; type Output = Int4;
@ -301,6 +324,26 @@ pub(crate) mod fallback {
} }
} }
impl std::ops::BitOr for Int4 {
type Output = Int4;
fn bitor(self, other: Self) -> Int4 {
Int4 {
v: [
self.v[0] | other.v[0],
self.v[1] | other.v[1],
self.v[2] | other.v[2],
self.v[3] | other.v[3],
],
}
}
}
impl std::ops::BitOrAssign for Int4 {
fn bitor_assign(&mut self, other: Self) {
*self = *self | other;
}
}
impl std::ops::BitXor for Int4 { impl std::ops::BitXor for Int4 {
type Output = Int4; type Output = Int4;
fn bitxor(self, other: Self) -> Int4 { fn bitxor(self, other: Self) -> Int4 {