Skip to content

Instantly share code, notes, and snippets.

@mooman219
Last active August 15, 2019 07:58
Show Gist options
  • Select an option

  • Save mooman219/14eddcda19cd7520b466e6eaa65dbcf9 to your computer and use it in GitHub Desktop.

Select an option

Save mooman219/14eddcda19cd7520b466e6eaa65dbcf9 to your computer and use it in GitHub Desktop.
#[cfg(not(target_feature = "sse"))]
fn accumulate(src: &[f32]) -> Vec<u8> {
let mut acc = 0.0;
src.iter()
.map(|c| {
acc += c;
let y = acc.abs();
let y = if y < 1.0 {
y
} else {
1.0
};
(255.0 * y) as u8
})
.collect()
}
pub fn accumulate(src: &[f32]) -> Vec<u8> {
let len = src.len();
let n = (len + 3) & !3;
let mut dst: Vec<u8> = vec![0; n];
unsafe {
let mut offset = _mm_setzero_ps();
let sign_mask = _mm_set1_ps(-0.);
let mask = _mm_set1_epi32(0x0c080400);
for i in (0..n).step_by(4) {
let mut x = _mm_loadu_ps(&src[i]);
x = _mm_add_ps(x, _mm_castsi128_ps(_mm_slli_si128(_mm_castps_si128(x), 4)));
x = _mm_add_ps(x, _mm_shuffle_ps(_mm_setzero_ps(), x, 0x40));
x = _mm_add_ps(x, offset);
let mut y = _mm_andnot_ps(sign_mask, x); // fabs(x)
y = _mm_min_ps(y, _mm_set1_ps(1.0));
y = _mm_mul_ps(y, _mm_set1_ps(255.0));
let mut z = _mm_cvttps_epi32(y);
z = _mm_shuffle_epi8(z, mask);
_mm_store_ss(core::mem::transmute(&dst[i]), _mm_castsi128_ps(z));
offset = _mm_shuffle_ps(x, x, _mm_shuffle_(3, 3, 3, 3));
}
dst.set_len(len);
}
dst
}
const fn _mm_shuffle_(z: i32, y: i32, x: i32, w: i32) -> i32 {
(z << 6) | (y << 4) | (x << 2) | w
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment