From 7290d42c04b4c5f3c5dc679923a57d070ba5390e Mon Sep 17 00:00:00 2001 From: Norbert Nemec Date: Sun, 1 Sep 2019 16:26:27 +0200 Subject: [PATCH] split off code into vector_simd.rs --- src/lib.rs | 3 + src/vector.rs | 406 --------------------------------------------- src/vector_simd.rs | 386 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 389 insertions(+), 406 deletions(-) create mode 100644 src/vector_simd.rs diff --git a/src/lib.rs b/src/lib.rs index 30d2a66..a803ef7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -101,6 +101,9 @@ mod matrix; mod quaternion; mod vector; +#[cfg(feature = "simd")] +mod vector_simd; + mod angle; mod euler; mod point; diff --git a/src/vector.rs b/src/vector.rs index 8a7e091..1e58c4a 100644 --- a/src/vector.rs +++ b/src/vector.rs @@ -30,13 +30,6 @@ use angle::Rad; use approx; use num::{BaseFloat, BaseNum}; -#[cfg(feature = "simd")] -use simd::f32x4 as Simdf32x4; -#[cfg(feature = "simd")] -use simd::i32x4 as Simdi32x4; -#[cfg(feature = "simd")] -use simd::u32x4 as Simdu32x4; - #[cfg(feature = "mint")] use mint; @@ -598,405 +591,6 @@ impl fmt::Debug for Vector4 { } } -#[cfg(feature = "simd")] -impl From for Vector4 { - #[inline] - fn from(f: Simdf32x4) -> Self { - unsafe { - let mut ret: Self = mem::uninitialized(); - { - let ret_mut: &mut [f32; 4] = ret.as_mut(); - f.store(ret_mut.as_mut(), 0 as usize); - } - ret - } - } -} - -#[cfg(feature = "simd")] -impl Vector4 { - /// Compute and return the square root of each element. - #[inline] - pub fn sqrt_element_wide(self) -> Self { - let s: Simdf32x4 = self.into(); - s.sqrt().into() - } - - /// Compute and return the reciprocal of the square root of each element. - #[inline] - pub fn rsqrt_element_wide(self) -> Self { - let s: Simdf32x4 = self.into(); - s.approx_rsqrt().into() - } - - /// Compute and return the reciprocal of each element. - #[inline] - pub fn recip_element_wide(self) -> Self { - let s: Simdf32x4 = self.into(); - s.approx_reciprocal().into() - } -} - -#[cfg(feature = "simd")] -impl Into for Vector4 { - #[inline] - fn into(self) -> Simdf32x4 { - let self_ref: &[f32; 4] = self.as_ref(); - Simdf32x4::load(self_ref.as_ref(), 0 as usize) - } -} - -#[cfg(feature = "simd")] -impl_operator_simd!{ - [Simdf32x4]; Add> for Vector4 { - fn add(lhs, rhs) -> Vector4 { - (lhs + rhs).into() - } - } -} - -#[cfg(feature = "simd")] -impl_operator_simd!{ - [Simdf32x4]; Sub> for Vector4 { - fn sub(lhs, rhs) -> Vector4 { - (lhs - rhs).into() - } - } -} - -#[cfg(feature = "simd")] -impl_operator_simd!{@rs - [Simdf32x4]; Mul for Vector4 { - fn mul(lhs, rhs) -> Vector4 { - (lhs * rhs).into() - } - } -} - -#[cfg(feature = "simd")] -impl_operator_simd!{@rs - [Simdf32x4]; Div for Vector4 { - fn div(lhs, rhs) -> Vector4 { - (lhs / rhs).into() - } - } -} - -#[cfg(feature = "simd")] -impl_operator_simd!{ - [Simdf32x4]; Neg for Vector4 { - fn neg(lhs) -> Vector4 { - (-lhs).into() - } - } -} - -#[cfg(feature = "simd")] -impl AddAssign for Vector4 { - #[inline] - fn add_assign(&mut self, rhs: Self) { - let s: Simdf32x4 = (*self).into(); - let rhs: Simdf32x4 = rhs.into(); - *self = (s + rhs).into(); - } -} - -#[cfg(feature = "simd")] -impl SubAssign for Vector4 { - #[inline] - fn sub_assign(&mut self, rhs: Self) { - let s: Simdf32x4 = (*self).into(); - let rhs: Simdf32x4 = rhs.into(); - *self = (s - rhs).into(); - } -} - -#[cfg(feature = "simd")] -impl MulAssign for Vector4 { - fn mul_assign(&mut self, other: f32) { - let s: Simdf32x4 = (*self).into(); - let other = Simdf32x4::splat(other); - *self = (s * other).into(); - } -} - -#[cfg(feature = "simd")] -impl DivAssign for Vector4 { - fn div_assign(&mut self, other: f32) { - let s: Simdf32x4 = (*self).into(); - let other = Simdf32x4::splat(other); - *self = (s / other).into(); - } -} - -#[cfg(feature = "simd")] -impl ElementWise for Vector4 { - #[inline] - fn add_element_wise(self, rhs: Vector4) -> Vector4 { - self + rhs - } - #[inline] - fn sub_element_wise(self, rhs: Vector4) -> Vector4 { - self - rhs - } - #[inline] - fn mul_element_wise(self, rhs: Vector4) -> Vector4 { - let s: Simdf32x4 = self.into(); - let rhs: Simdf32x4 = rhs.into(); - (s * rhs).into() - } - #[inline] - fn div_element_wise(self, rhs: Vector4) -> Vector4 { - let s: Simdf32x4 = self.into(); - let rhs: Simdf32x4 = rhs.into(); - (s / rhs).into() - } - - #[inline] - fn add_assign_element_wise(&mut self, rhs: Vector4) { - (*self) += rhs; - } - - #[inline] - fn sub_assign_element_wise(&mut self, rhs: Vector4) { - (*self) -= rhs; - } - - #[inline] - fn mul_assign_element_wise(&mut self, rhs: Vector4) { - let s: Simdf32x4 = (*self).into(); - let rhs: Simdf32x4 = rhs.into(); - *self = (s * rhs).into(); - } - - #[inline] - fn div_assign_element_wise(&mut self, rhs: Vector4) { - let s: Simdf32x4 = (*self).into(); - let rhs: Simdf32x4 = rhs.into(); - *self = (s * rhs).into(); - } -} - -#[cfg(feature = "simd")] -impl ElementWise for Vector4 { - #[inline] - fn add_element_wise(self, rhs: f32) -> Vector4 { - let s: Simdf32x4 = self.into(); - let rhs = Simdf32x4::splat(rhs); - (s + rhs).into() - } - - #[inline] - fn sub_element_wise(self, rhs: f32) -> Vector4 { - let s: Simdf32x4 = self.into(); - let rhs = Simdf32x4::splat(rhs); - (s - rhs).into() - } - - #[inline] - fn mul_element_wise(self, rhs: f32) -> Vector4 { - self * rhs - } - - #[inline] - fn div_element_wise(self, rhs: f32) -> Vector4 { - self / rhs - } - - #[inline] - fn add_assign_element_wise(&mut self, rhs: f32) { - let s: Simdf32x4 = (*self).into(); - let rhs = Simdf32x4::splat(rhs); - *self = (s + rhs).into(); - } - - #[inline] - fn sub_assign_element_wise(&mut self, rhs: f32) { - let s: Simdf32x4 = (*self).into(); - let rhs = Simdf32x4::splat(rhs); - *self = (s - rhs).into(); - } - - #[inline] - fn mul_assign_element_wise(&mut self, rhs: f32) { - (*self) *= rhs; - } - - #[inline] - fn div_assign_element_wise(&mut self, rhs: f32) { - (*self) /= rhs; - } -} - -#[cfg(feature = "simd")] -impl From for Vector4 { - #[inline] - fn from(f: Simdi32x4) -> Self { - unsafe { - let mut ret: Self = mem::uninitialized(); - { - let ret_mut: &mut [i32; 4] = ret.as_mut(); - f.store(ret_mut.as_mut(), 0 as usize); - } - ret - } - } -} - -#[cfg(feature = "simd")] -impl Into for Vector4 { - #[inline] - fn into(self) -> Simdi32x4 { - let self_ref: &[i32; 4] = self.as_ref(); - Simdi32x4::load(self_ref.as_ref(), 0 as usize) - } -} - -#[cfg(feature = "simd")] -impl_operator_simd!{ - [Simdi32x4]; Add> for Vector4 { - fn add(lhs, rhs) -> Vector4 { - (lhs + rhs).into() - } - } -} - -#[cfg(feature = "simd")] -impl_operator_simd!{ - [Simdi32x4]; Sub> for Vector4 { - fn sub(lhs, rhs) -> Vector4 { - (lhs - rhs).into() - } - } -} - -#[cfg(feature = "simd")] -impl_operator_simd!{@rs - [Simdi32x4]; Mul for Vector4 { - fn mul(lhs, rhs) -> Vector4 { - (lhs * rhs).into() - } - } -} - -#[cfg(feature = "simd")] -impl_operator_simd!{ - [Simdi32x4]; Neg for Vector4 { - fn neg(lhs) -> Vector4 { - (-lhs).into() - } - } -} - -#[cfg(feature = "simd")] -impl AddAssign for Vector4 { - #[inline] - fn add_assign(&mut self, rhs: Self) { - let s: Simdi32x4 = (*self).into(); - let rhs: Simdi32x4 = rhs.into(); - *self = (s + rhs).into(); - } -} - -#[cfg(feature = "simd")] -impl SubAssign for Vector4 { - #[inline] - fn sub_assign(&mut self, rhs: Self) { - let s: Simdi32x4 = (*self).into(); - let rhs: Simdi32x4 = rhs.into(); - *self = (s - rhs).into(); - } -} - -#[cfg(feature = "simd")] -impl MulAssign for Vector4 { - fn mul_assign(&mut self, other: i32) { - let s: Simdi32x4 = (*self).into(); - let other = Simdi32x4::splat(other); - *self = (s * other).into(); - } -} - -#[cfg(feature = "simd")] -impl From for Vector4 { - #[inline] - fn from(f: Simdu32x4) -> Self { - unsafe { - let mut ret: Self = mem::uninitialized(); - { - let ret_mut: &mut [u32; 4] = ret.as_mut(); - f.store(ret_mut.as_mut(), 0 as usize); - } - ret - } - } -} - -#[cfg(feature = "simd")] -impl Into for Vector4 { - #[inline] - fn into(self) -> Simdu32x4 { - let self_ref: &[u32; 4] = self.as_ref(); - Simdu32x4::load(self_ref.as_ref(), 0 as usize) - } -} - -#[cfg(feature = "simd")] -impl_operator_simd!{ - [Simdu32x4]; Add> for Vector4 { - fn add(lhs, rhs) -> Vector4 { - (lhs + rhs).into() - } - } -} - -#[cfg(feature = "simd")] -impl_operator_simd!{ - [Simdu32x4]; Sub> for Vector4 { - fn sub(lhs, rhs) -> Vector4 { - (lhs - rhs).into() - } - } -} - -#[cfg(feature = "simd")] -impl_operator_simd!{@rs - [Simdu32x4]; Mul for Vector4 { - fn mul(lhs, rhs) -> Vector4 { - (lhs * rhs).into() - } - } -} - -#[cfg(feature = "simd")] -impl AddAssign for Vector4 { - #[inline] - fn add_assign(&mut self, rhs: Self) { - let s: Simdu32x4 = (*self).into(); - let rhs: Simdu32x4 = rhs.into(); - *self = (s + rhs).into(); - } -} - -#[cfg(feature = "simd")] -impl SubAssign for Vector4 { - #[inline] - fn sub_assign(&mut self, rhs: Self) { - let s: Simdu32x4 = (*self).into(); - let rhs: Simdu32x4 = rhs.into(); - *self = (s - rhs).into(); - } -} - -#[cfg(feature = "simd")] -impl MulAssign for Vector4 { - fn mul_assign(&mut self, other: u32) { - let s: Simdu32x4 = (*self).into(); - let other = Simdu32x4::splat(other); - *self = (s * other).into(); - } -} - #[cfg(feature = "mint")] impl_mint_conversions!(Vector2 { x, y }, Vector2); #[cfg(feature = "mint")] diff --git a/src/vector_simd.rs b/src/vector_simd.rs new file mode 100644 index 0000000..7d89404 --- /dev/null +++ b/src/vector_simd.rs @@ -0,0 +1,386 @@ +// Copyright 2013-2014 The CGMath Developers. For a full listing of the authors, +// refer to the Cargo.toml file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use simd::f32x4 as Simdf32x4; +use simd::i32x4 as Simdi32x4; +use simd::u32x4 as Simdu32x4; + +impl From for Vector4 { + #[inline] + fn from(f: Simdf32x4) -> Self { + unsafe { + let mut ret: Self = mem::uninitialized(); + { + let ret_mut: &mut [f32; 4] = ret.as_mut(); + f.store(ret_mut.as_mut(), 0 as usize); + } + ret + } + } +} + +impl Vector4 { + /// Compute and return the square root of each element. + #[inline] + pub fn sqrt_element_wide(self) -> Self { + let s: Simdf32x4 = self.into(); + s.sqrt().into() + } + + /// Compute and return the reciprocal of the square root of each element. + #[inline] + pub fn rsqrt_element_wide(self) -> Self { + let s: Simdf32x4 = self.into(); + s.approx_rsqrt().into() + } + + /// Compute and return the reciprocal of each element. + #[inline] + pub fn recip_element_wide(self) -> Self { + let s: Simdf32x4 = self.into(); + s.approx_reciprocal().into() + } +} + +impl Into for Vector4 { + #[inline] + fn into(self) -> Simdf32x4 { + let self_ref: &[f32; 4] = self.as_ref(); + Simdf32x4::load(self_ref.as_ref(), 0 as usize) + } +} + +impl_operator_simd!{ + [Simdf32x4]; Add> for Vector4 { + fn add(lhs, rhs) -> Vector4 { + (lhs + rhs).into() + } + } +} + +impl_operator_simd!{ + [Simdf32x4]; Sub> for Vector4 { + fn sub(lhs, rhs) -> Vector4 { + (lhs - rhs).into() + } + } +} + +impl_operator_simd!{@rs + [Simdf32x4]; Mul for Vector4 { + fn mul(lhs, rhs) -> Vector4 { + (lhs * rhs).into() + } + } +} + +impl_operator_simd!{@rs + [Simdf32x4]; Div for Vector4 { + fn div(lhs, rhs) -> Vector4 { + (lhs / rhs).into() + } + } +} + +impl_operator_simd!{ + [Simdf32x4]; Neg for Vector4 { + fn neg(lhs) -> Vector4 { + (-lhs).into() + } + } +} + +impl AddAssign for Vector4 { + #[inline] + fn add_assign(&mut self, rhs: Self) { + let s: Simdf32x4 = (*self).into(); + let rhs: Simdf32x4 = rhs.into(); + *self = (s + rhs).into(); + } +} + +impl SubAssign for Vector4 { + #[inline] + fn sub_assign(&mut self, rhs: Self) { + let s: Simdf32x4 = (*self).into(); + let rhs: Simdf32x4 = rhs.into(); + *self = (s - rhs).into(); + } +} + +impl MulAssign for Vector4 { + fn mul_assign(&mut self, other: f32) { + let s: Simdf32x4 = (*self).into(); + let other = Simdf32x4::splat(other); + *self = (s * other).into(); + } +} + +impl DivAssign for Vector4 { + fn div_assign(&mut self, other: f32) { + let s: Simdf32x4 = (*self).into(); + let other = Simdf32x4::splat(other); + *self = (s / other).into(); + } +} + +impl ElementWise for Vector4 { + #[inline] + fn add_element_wise(self, rhs: Vector4) -> Vector4 { + self + rhs + } + #[inline] + fn sub_element_wise(self, rhs: Vector4) -> Vector4 { + self - rhs + } + #[inline] + fn mul_element_wise(self, rhs: Vector4) -> Vector4 { + let s: Simdf32x4 = self.into(); + let rhs: Simdf32x4 = rhs.into(); + (s * rhs).into() + } + #[inline] + fn div_element_wise(self, rhs: Vector4) -> Vector4 { + let s: Simdf32x4 = self.into(); + let rhs: Simdf32x4 = rhs.into(); + (s / rhs).into() + } + + #[inline] + fn add_assign_element_wise(&mut self, rhs: Vector4) { + (*self) += rhs; + } + + #[inline] + fn sub_assign_element_wise(&mut self, rhs: Vector4) { + (*self) -= rhs; + } + + #[inline] + fn mul_assign_element_wise(&mut self, rhs: Vector4) { + let s: Simdf32x4 = (*self).into(); + let rhs: Simdf32x4 = rhs.into(); + *self = (s * rhs).into(); + } + + #[inline] + fn div_assign_element_wise(&mut self, rhs: Vector4) { + let s: Simdf32x4 = (*self).into(); + let rhs: Simdf32x4 = rhs.into(); + *self = (s * rhs).into(); + } +} + +impl ElementWise for Vector4 { + #[inline] + fn add_element_wise(self, rhs: f32) -> Vector4 { + let s: Simdf32x4 = self.into(); + let rhs = Simdf32x4::splat(rhs); + (s + rhs).into() + } + + #[inline] + fn sub_element_wise(self, rhs: f32) -> Vector4 { + let s: Simdf32x4 = self.into(); + let rhs = Simdf32x4::splat(rhs); + (s - rhs).into() + } + + #[inline] + fn mul_element_wise(self, rhs: f32) -> Vector4 { + self * rhs + } + + #[inline] + fn div_element_wise(self, rhs: f32) -> Vector4 { + self / rhs + } + + #[inline] + fn add_assign_element_wise(&mut self, rhs: f32) { + let s: Simdf32x4 = (*self).into(); + let rhs = Simdf32x4::splat(rhs); + *self = (s + rhs).into(); + } + + #[inline] + fn sub_assign_element_wise(&mut self, rhs: f32) { + let s: Simdf32x4 = (*self).into(); + let rhs = Simdf32x4::splat(rhs); + *self = (s - rhs).into(); + } + + #[inline] + fn mul_assign_element_wise(&mut self, rhs: f32) { + (*self) *= rhs; + } + + #[inline] + fn div_assign_element_wise(&mut self, rhs: f32) { + (*self) /= rhs; + } +} + +impl From for Vector4 { + #[inline] + fn from(f: Simdi32x4) -> Self { + unsafe { + let mut ret: Self = mem::uninitialized(); + { + let ret_mut: &mut [i32; 4] = ret.as_mut(); + f.store(ret_mut.as_mut(), 0 as usize); + } + ret + } + } +} + +impl Into for Vector4 { + #[inline] + fn into(self) -> Simdi32x4 { + let self_ref: &[i32; 4] = self.as_ref(); + Simdi32x4::load(self_ref.as_ref(), 0 as usize) + } +} + +impl_operator_simd!{ + [Simdi32x4]; Add> for Vector4 { + fn add(lhs, rhs) -> Vector4 { + (lhs + rhs).into() + } + } +} + +impl_operator_simd!{ + [Simdi32x4]; Sub> for Vector4 { + fn sub(lhs, rhs) -> Vector4 { + (lhs - rhs).into() + } + } +} + +impl_operator_simd!{@rs + [Simdi32x4]; Mul for Vector4 { + fn mul(lhs, rhs) -> Vector4 { + (lhs * rhs).into() + } + } +} + +impl_operator_simd!{ + [Simdi32x4]; Neg for Vector4 { + fn neg(lhs) -> Vector4 { + (-lhs).into() + } + } +} + +impl AddAssign for Vector4 { + #[inline] + fn add_assign(&mut self, rhs: Self) { + let s: Simdi32x4 = (*self).into(); + let rhs: Simdi32x4 = rhs.into(); + *self = (s + rhs).into(); + } +} + +impl SubAssign for Vector4 { + #[inline] + fn sub_assign(&mut self, rhs: Self) { + let s: Simdi32x4 = (*self).into(); + let rhs: Simdi32x4 = rhs.into(); + *self = (s - rhs).into(); + } +} + +impl MulAssign for Vector4 { + fn mul_assign(&mut self, other: i32) { + let s: Simdi32x4 = (*self).into(); + let other = Simdi32x4::splat(other); + *self = (s * other).into(); + } +} + +impl From for Vector4 { + #[inline] + fn from(f: Simdu32x4) -> Self { + unsafe { + let mut ret: Self = mem::uninitialized(); + { + let ret_mut: &mut [u32; 4] = ret.as_mut(); + f.store(ret_mut.as_mut(), 0 as usize); + } + ret + } + } +} + +impl Into for Vector4 { + #[inline] + fn into(self) -> Simdu32x4 { + let self_ref: &[u32; 4] = self.as_ref(); + Simdu32x4::load(self_ref.as_ref(), 0 as usize) + } +} + +impl_operator_simd!{ + [Simdu32x4]; Add> for Vector4 { + fn add(lhs, rhs) -> Vector4 { + (lhs + rhs).into() + } + } +} + +impl_operator_simd!{ + [Simdu32x4]; Sub> for Vector4 { + fn sub(lhs, rhs) -> Vector4 { + (lhs - rhs).into() + } + } +} + +impl_operator_simd!{@rs + [Simdu32x4]; Mul for Vector4 { + fn mul(lhs, rhs) -> Vector4 { + (lhs * rhs).into() + } + } +} + +impl AddAssign for Vector4 { + #[inline] + fn add_assign(&mut self, rhs: Self) { + let s: Simdu32x4 = (*self).into(); + let rhs: Simdu32x4 = rhs.into(); + *self = (s + rhs).into(); + } +} + +impl SubAssign for Vector4 { + #[inline] + fn sub_assign(&mut self, rhs: Self) { + let s: Simdu32x4 = (*self).into(); + let rhs: Simdu32x4 = rhs.into(); + *self = (s - rhs).into(); + } +} + +impl MulAssign for Vector4 { + fn mul_assign(&mut self, other: u32) { + let s: Simdu32x4 = (*self).into(); + let other = Simdu32x4::splat(other); + *self = (s * other).into(); + } +}