From c48839d5f3af9fd0147dcfdc16fe46e171037275 Mon Sep 17 00:00:00 2001 From: Nathan Vegdahl Date: Sat, 23 Jan 2021 00:55:54 +0900 Subject: [PATCH] An even better Owen scrambling hash. --- sub_crates/sobol/src/lib.rs | 12 +++---- sub_crates/sobol/src/wide.rs | 65 ++++++++++++++++++++++++++++++------ 2 files changed, 60 insertions(+), 17 deletions(-) diff --git a/sub_crates/sobol/src/lib.rs b/sub_crates/sobol/src/lib.rs index b149ea8..64ca5ec 100644 --- a/sub_crates/sobol/src/lib.rs +++ b/sub_crates/sobol/src/lib.rs @@ -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 { let scramble = hash(scramble); - n = n.wrapping_add(scramble); - n ^= n.wrapping_mul(0x3354734a); 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 } @@ -79,10 +79,10 @@ fn lk_scramble(mut n: u32, scramble: u32) -> u32 { fn lk_scramble_int4(mut n: Int4, scramble: u32) -> Int4 { let scramble = hash_int4([scramble; 4].into()); - n += scramble; - n ^= n * [0x3354734a; 4].into(); n += n << 2; - n ^= n * (scramble & [!1; 4].into()); + n ^= n * [0xfe9b5742; 4].into(); + n += scramble; + n *= scramble | [1; 4].into(); n } diff --git a/sub_crates/sobol/src/wide.rs b/sub_crates/sobol/src/wide.rs index 831648d..f90940f 100644 --- a/sub_crates/sobol/src/wide.rs +++ b/sub_crates/sobol/src/wide.rs @@ -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 { 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 for 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 { type Output = Int4; fn bitxor(self, other: Self) -> Int4 {