15% reductions in instr count
This commit is contained in:
parent
36293e75e6
commit
bcda26a512
|
@ -151,34 +151,6 @@ pub(crate) mod constmatrix {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
use super::Float;
|
|
||||||
impl<const M: usize, const N: usize> Matrix<Float, M, N> {
|
|
||||||
pub fn matmul_fast<const P: usize>(
|
|
||||||
&self,
|
|
||||||
other: &Matrix<Float, N, P>,
|
|
||||||
) -> Matrix<Float, M, P> {
|
|
||||||
let mut out = Matrix::default();
|
|
||||||
self.matmul_into_fast(other, &mut out);
|
|
||||||
out
|
|
||||||
}
|
|
||||||
pub fn matmul_into_fast<const P: usize>(
|
|
||||||
&self,
|
|
||||||
other: &Matrix<Float, N, P>,
|
|
||||||
out: &mut Matrix<Float, M, P>,
|
|
||||||
) {
|
|
||||||
use core::intrinsics::{fadd_fast, fmul_fast};
|
|
||||||
for i in 0..M {
|
|
||||||
for j in 0..P {
|
|
||||||
let mut t = 0.0;
|
|
||||||
for k in 0..N {
|
|
||||||
t = unsafe { fadd_fast(t, fmul_fast(self[(i, k)], other[(k, j)])) }
|
|
||||||
}
|
|
||||||
out[(i, j)] = t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{super::*, *};
|
use super::{super::*, *};
|
||||||
|
@ -268,6 +240,90 @@ pub(crate) fn diff_op_1d_matrix<const M: usize, const N: usize, const D: usize>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod fastfloat {
|
||||||
|
use super::*;
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[derive(Debug, PartialEq, Default)]
|
||||||
|
pub(crate) struct FastFloat(Float);
|
||||||
|
|
||||||
|
use core::intrinsics::{fadd_fast, fmul_fast};
|
||||||
|
|
||||||
|
impl core::ops::Mul for FastFloat {
|
||||||
|
type Output = Self;
|
||||||
|
fn mul(self, o: Self) -> Self::Output {
|
||||||
|
unsafe { Self(fmul_fast(self.0, o.0)) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl core::ops::MulAssign<FastFloat> for FastFloat {
|
||||||
|
fn mul_assign(&mut self, o: FastFloat) {
|
||||||
|
unsafe {
|
||||||
|
self.0 = fmul_fast(self.0, o.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl core::ops::MulAssign<&FastFloat> for FastFloat {
|
||||||
|
fn mul_assign(&mut self, o: &FastFloat) {
|
||||||
|
unsafe {
|
||||||
|
self.0 = fmul_fast(self.0, o.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl core::ops::MulAssign<FastFloat> for &mut FastFloat {
|
||||||
|
fn mul_assign(&mut self, o: FastFloat) {
|
||||||
|
unsafe {
|
||||||
|
self.0 = fmul_fast(self.0, o.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl core::ops::MulAssign<&FastFloat> for &mut FastFloat {
|
||||||
|
fn mul_assign(&mut self, o: &FastFloat) {
|
||||||
|
unsafe {
|
||||||
|
self.0 = fmul_fast(self.0, o.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl core::ops::AddAssign for FastFloat {
|
||||||
|
fn add_assign(&mut self, o: Self) {
|
||||||
|
unsafe {
|
||||||
|
self.0 = fadd_fast(self.0, o.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl core::ops::Mul for &FastFloat {
|
||||||
|
type Output = FastFloat;
|
||||||
|
fn mul(self, o: Self) -> Self::Output {
|
||||||
|
unsafe { FastFloat(fmul_fast(self.0, o.0)) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl core::ops::MulAssign<&Float> for FastFloat {
|
||||||
|
fn mul_assign(&mut self, o: &Float) {
|
||||||
|
unsafe {
|
||||||
|
self.0 = fmul_fast(self.0, *o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl core::ops::MulAssign<&Float> for &mut FastFloat {
|
||||||
|
fn mul_assign(&mut self, o: &Float) {
|
||||||
|
unsafe {
|
||||||
|
self.0 = fmul_fast(self.0, *o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Float> for FastFloat {
|
||||||
|
fn from(f: Float) -> Self {
|
||||||
|
Self(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
use fastfloat::FastFloat;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn diff_op_1d_slice_matrix<const M: usize, const N: usize, const D: usize>(
|
pub(crate) fn diff_op_1d_slice_matrix<const M: usize, const N: usize, const D: usize>(
|
||||||
block: &Matrix<Float, M, N>,
|
block: &Matrix<Float, M, N>,
|
||||||
|
@ -277,6 +333,13 @@ pub(crate) fn diff_op_1d_slice_matrix<const M: usize, const N: usize, const D: u
|
||||||
prev: &[Float],
|
prev: &[Float],
|
||||||
fut: &mut [Float],
|
fut: &mut [Float],
|
||||||
) {
|
) {
|
||||||
|
use std::mem::transmute;
|
||||||
|
let block = unsafe { transmute::<_, &Matrix<FastFloat, M, N>>(block) };
|
||||||
|
let endblock = unsafe { transmute::<_, &Matrix<FastFloat, M, N>>(endblock) };
|
||||||
|
let diag = unsafe { transmute::<_, &RowVector<FastFloat, D>>(diag) };
|
||||||
|
let prev = unsafe { transmute::<_, &[FastFloat]>(prev) };
|
||||||
|
let fut = unsafe { transmute::<_, &mut [FastFloat]>(fut) };
|
||||||
|
|
||||||
assert_eq!(prev.len(), fut.len());
|
assert_eq!(prev.len(), fut.len());
|
||||||
let nx = prev.len();
|
let nx = prev.len();
|
||||||
assert!(nx >= 2 * M);
|
assert!(nx >= 2 * M);
|
||||||
|
@ -289,14 +352,14 @@ pub(crate) fn diff_op_1d_slice_matrix<const M: usize, const N: usize, const D: u
|
||||||
} else {
|
} else {
|
||||||
1.0 / (nx - 1) as Float
|
1.0 / (nx - 1) as Float
|
||||||
};
|
};
|
||||||
let idx = 1.0 / dx;
|
let idx = FastFloat::from(1.0 / dx);
|
||||||
|
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
{
|
{
|
||||||
let prev = ColVector::<_, N>::map_to_col(prev.array_windows::<N>().nth(0).unwrap());
|
let prev = ColVector::<_, N>::map_to_col(prev.array_windows::<N>().nth(0).unwrap());
|
||||||
let fut = ColVector::<_, M>::map_to_col_mut((&mut fut[0..M]).try_into().unwrap());
|
let fut = ColVector::<_, M>::map_to_col_mut((&mut fut[0..M]).try_into().unwrap());
|
||||||
|
|
||||||
block.matmul_into_fast(prev, fut);
|
block.matmul_into(prev, fut);
|
||||||
*fut *= &idx;
|
*fut *= &idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,10 +374,10 @@ pub(crate) fn diff_op_1d_slice_matrix<const M: usize, const N: usize, const D: u
|
||||||
.take(nx - 2 * M)
|
.take(nx - 2 * M)
|
||||||
{
|
{
|
||||||
// impl From here?
|
// impl From here?
|
||||||
let fut = ColVector::<Float, 1>::map_to_col_mut(f);
|
let fut = ColVector::<_, 1>::map_to_col_mut(f);
|
||||||
let prev = ColVector::<_, D>::map_to_col(window);
|
let prev = ColVector::<_, D>::map_to_col(window);
|
||||||
|
|
||||||
diag.matmul_into_fast(prev, fut);
|
diag.matmul_into(prev, fut);
|
||||||
*fut *= &idx;
|
*fut *= &idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,7 +386,7 @@ pub(crate) fn diff_op_1d_slice_matrix<const M: usize, const N: usize, const D: u
|
||||||
let prev = ColVector::<_, N>::map_to_col(prev);
|
let prev = ColVector::<_, N>::map_to_col(prev);
|
||||||
let fut = ColVector::<_, M>::map_to_col_mut((&mut fut[nx - M..]).try_into().unwrap());
|
let fut = ColVector::<_, M>::map_to_col_mut((&mut fut[nx - M..]).try_into().unwrap());
|
||||||
|
|
||||||
endblock.matmul_into_fast(prev, fut);
|
endblock.matmul_into(prev, fut);
|
||||||
*fut *= &idx;
|
*fut *= &idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue