/home/noah/src/trueno/src/backends/avx2/ops/arithmetic.rs
Line | Count | Source |
1 | | //! AVX2 arithmetic operations (add, sub, mul, div). |
2 | | |
3 | | #[cfg(target_arch = "x86_64")] |
4 | | use std::arch::x86_64::*; |
5 | | |
6 | | /// AVX2 vector addition. |
7 | | #[inline] |
8 | | #[target_feature(enable = "avx2")] |
9 | 15 | pub unsafe fn add(a: &[f32], b: &[f32], result: &mut [f32]) { |
10 | 15 | let len = a.len(); |
11 | 15 | let mut i = 0; |
12 | | |
13 | 26 | while i + 8 <= len { |
14 | 11 | let va = _mm256_loadu_ps(a.as_ptr().add(i)); |
15 | 11 | let vb = _mm256_loadu_ps(b.as_ptr().add(i)); |
16 | 11 | let vresult = _mm256_add_ps(va, vb); |
17 | 11 | _mm256_storeu_ps(result.as_mut_ptr().add(i), vresult); |
18 | 11 | i += 8; |
19 | 11 | } |
20 | | |
21 | 15 | for j8 in i..len { |
22 | 8 | result[j] = a[j] + b[j]; |
23 | 8 | } |
24 | 15 | } |
25 | | |
26 | | /// AVX2 vector subtraction. |
27 | | #[inline] |
28 | | #[target_feature(enable = "avx2")] |
29 | 15 | pub unsafe fn sub(a: &[f32], b: &[f32], result: &mut [f32]) { |
30 | 15 | let len = a.len(); |
31 | 15 | let mut i = 0; |
32 | | |
33 | 26 | while i + 8 <= len { |
34 | 11 | let va = _mm256_loadu_ps(a.as_ptr().add(i)); |
35 | 11 | let vb = _mm256_loadu_ps(b.as_ptr().add(i)); |
36 | 11 | let vresult = _mm256_sub_ps(va, vb); |
37 | 11 | _mm256_storeu_ps(result.as_mut_ptr().add(i), vresult); |
38 | 11 | i += 8; |
39 | 11 | } |
40 | | |
41 | 15 | for j8 in i..len { |
42 | 8 | result[j] = a[j] - b[j]; |
43 | 8 | } |
44 | 15 | } |
45 | | |
46 | | /// AVX2 vector multiplication. |
47 | | #[inline] |
48 | | #[target_feature(enable = "avx2")] |
49 | 61 | pub unsafe fn mul(a: &[f32], b: &[f32], result: &mut [f32]) { |
50 | 61 | let len = a.len(); |
51 | 61 | let mut i = 0; |
52 | | |
53 | 105 | while i + 8 <= len { |
54 | 44 | let va = _mm256_loadu_ps(a.as_ptr().add(i)); |
55 | 44 | let vb = _mm256_loadu_ps(b.as_ptr().add(i)); |
56 | 44 | let vresult = _mm256_mul_ps(va, vb); |
57 | 44 | _mm256_storeu_ps(result.as_mut_ptr().add(i), vresult); |
58 | 44 | i += 8; |
59 | 44 | } |
60 | | |
61 | 61 | for j36 in i..len { |
62 | 36 | result[j] = a[j] * b[j]; |
63 | 36 | } |
64 | 61 | } |
65 | | |
66 | | /// AVX2 vector division. |
67 | | #[inline] |
68 | | #[target_feature(enable = "avx2")] |
69 | 0 | pub unsafe fn div(a: &[f32], b: &[f32], result: &mut [f32]) { |
70 | 0 | let len = a.len(); |
71 | 0 | let mut i = 0; |
72 | | |
73 | 0 | while i + 8 <= len { |
74 | 0 | let va = _mm256_loadu_ps(a.as_ptr().add(i)); |
75 | 0 | let vb = _mm256_loadu_ps(b.as_ptr().add(i)); |
76 | 0 | let vresult = _mm256_div_ps(va, vb); |
77 | 0 | _mm256_storeu_ps(result.as_mut_ptr().add(i), vresult); |
78 | 0 | i += 8; |
79 | 0 | } |
80 | | |
81 | 0 | for j in i..len { |
82 | 0 | result[j] = a[j] / b[j]; |
83 | 0 | } |
84 | 0 | } |