xsynth_core/helpers/
simd.rs

1use simdeez::*; // nuts
2
3use simdeez::prelude::*;
4
5/// Sum the values of `source` to the values of `target`, writing to `target`.
6///
7/// Uses runtime selected SIMD operations.
8pub fn sum_simd(source: &[f32], target: &mut [f32]) {
9    simd_runtime_generate!(
10        // Altered code from the SIMD example here https://github.com/jackmott/simdeez
11        fn sum(source: &[f32], target: &mut [f32]) {
12            let mut source = &source[..source.len()];
13            let mut target = &mut target[..source.len()];
14
15            loop {
16                let src = S::Vf32::load_from_slice(source);
17                let src2 = S::Vf32::load_from_slice(target);
18                let sum = src + src2;
19
20                sum.copy_to_slice(target);
21
22                if source.len() <= S::Vf32::WIDTH {
23                    break;
24                }
25
26                source = &source[S::Vf32::WIDTH..];
27                target = &mut target[S::Vf32::WIDTH..];
28            }
29        }
30    );
31
32    sum(source, target);
33}
34
35#[cfg(test)]
36mod tests {
37    use super::sum_simd;
38
39    #[test]
40    fn test_simd_add() {
41        let src = vec![1.0, 2.0, 3.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
42        let mut dst = vec![0.0, 1.0, 3.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0];
43        sum_simd(&src, &mut dst);
44        assert_eq!(dst, vec![1.0, 3.0, 6.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0]);
45    }
46}