Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Michael Black
OpenXG-RAN
Commits
bf219fc2
Commit
bf219fc2
authored
2 years ago
by
Laurent Thomas
Committed by
laurent
2 years ago
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
avx2 and better simd algo
parent
6d030ea2
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
31 additions
and
205 deletions
+31
-205
openair1/PHY/TOOLS/cmult_sv.c
openair1/PHY/TOOLS/cmult_sv.c
+29
-195
openair1/PHY/TOOLS/tools_defs.h
openair1/PHY/TOOLS/tools_defs.h
+2
-10
No files found.
openair1/PHY/TOOLS/cmult_sv.c
View file @
bf219fc2
...
@@ -144,205 +144,39 @@ void multadd_real_four_symbols_vector_complex_scalar(int16_t *x,
...
@@ -144,205 +144,39 @@ void multadd_real_four_symbols_vector_complex_scalar(int16_t *x,
_m_empty
();
_m_empty
();
}
}
#ifdef __AVX2__
/*
void
rotate_cpx_vector
(
int16_t
*
x
,
int rotate_cpx_vector(int16_t *x,
int16_t *alpha,
int16_t *y,
uint32_t N,
uint16_t output_shift,
uint8_t format)
{
// Multiply elementwise two complex vectors of N elements
// x - input 1 in the format |Re0 Im0 Re0 Im0|,......,|Re(N-1) Im(N-1) Re(N-1) Im(N-1)|
// We assume x1 with a dynamic of 15 bit maximum
//
// alpha - input 2 in the format |Re0 Im0|
// We assume x2 with a dynamic of 15 bit maximum
//
// y - output in the format |Re0 Im0 Re0 Im0|,......,|Re(N-1) Im(N-1) Re(N-1) Im(N-1)|
//
// N - the size f the vectors (this function does N cpx mpy. WARNING: N>=4;
//
// output_shift - shift at output to return in Q1.15
// format - 0 means alpha is in shuffled format, 1 means x is in shuffled format
uint32_t i; // loop counter
register __m128i m0,m1;
__m128i *x_128;
__m128i *y_128;
shift = _mm_cvtsi32_si128(output_shift);
x_128 = (__m128i *)&x[0];
if (format==0) { // alpha is in shuffled format for complex multiply
((int16_t *)&alpha_128)[0] = alpha[0];
((int16_t *)&alpha_128)[1] = -alpha[1];
((int16_t *)&alpha_128)[2] = alpha[1];
((int16_t *)&alpha_128)[3] = alpha[0];
((int16_t *)&alpha_128)[4] = alpha[0];
((int16_t *)&alpha_128)[5] = -alpha[1];
((int16_t *)&alpha_128)[6] = alpha[1];
((int16_t *)&alpha_128)[7] = alpha[0];
} else { // input is in shuffled format for complex multiply
((int16_t *)&alpha_128)[0] = alpha[0];
((int16_t *)&alpha_128)[1] = alpha[1];
((int16_t *)&alpha_128)[2] = alpha[0];
((int16_t *)&alpha_128)[3] = alpha[1];
((int16_t *)&alpha_128)[4] = alpha[0];
((int16_t *)&alpha_128)[5] = alpha[1];
((int16_t *)&alpha_128)[6] = alpha[0];
((int16_t *)&alpha_128)[7] = alpha[1];
}
y_128 = (__m128i *)&y[0];
// _mm_empty();
// return(0);
// we compute 4 cpx multiply for each loop
for(i=0; i<(N>>3); i++) {
m0 = _mm_madd_epi16(x_128[0],alpha_128); //pmaddwd_r2r(mm1,mm0); // 1- compute x1[0]*x2[0]
m0 = _mm_sra_epi32(m0,shift); // 1- shift right by shift in order to compensate for the input amplitude
m1=m0;
m0 = _mm_packs_epi32(m1,m0); // 1- pack in a 128 bit register [re im re im]
y_128[0] = _mm_unpacklo_epi32(m0,m0); // 1- pack in a 128 bit register [re im re im]
m0 = _mm_madd_epi16(x_128[1],alpha_128); //pmaddwd_r2r(mm1,mm0); // 1- compute x1[0]*x2[0]
m0 = _mm_sra_epi32(m0,shift); // 1- shift right by shift in order to compensate for the input amplitude
m1 = m0;
m1 = _mm_packs_epi32(m1,m0); // 1- pack in a 128 bit register [re im re im]
y_128[1] = _mm_unpacklo_epi32(m1,m1); // 1- pack in a 128 bit register [re im re im]
m0 = _mm_madd_epi16(x_128[2],alpha_128); //pmaddwd_r2r(mm1,mm0); // 1- compute x1[0]*x2[0]
m0 = _mm_sra_epi32(m0,shift); // 1- shift right by shift in order to compensate for the input amplitude
m1 = m0;
m1 = _mm_packs_epi32(m1,m0); // 1- pack in a 128 bit register [re im re im]
y_128[2] = _mm_unpacklo_epi32(m1,m1); // 1- pack in a 128 bit register [re im re im]
m0 = _mm_madd_epi16(x_128[3],alpha_128); //pmaddwd_r2r(mm1,mm0); // 1- compute x1[0]*x2[0]
m0 = _mm_sra_epi32(m0,shift); // 1- shift right by shift in order to compensate for the input amplitude
m1 = m0;
m1 = _mm_packs_epi32(m1,m0); // 1- pack in a 128 bit register [re im re im]
y_128[3] = _mm_unpacklo_epi32(m1,m1); // 1- pack in a 128 bit register [re im re im]
if (format==1) { // Put output in proper format (Re,-Im,Im,Re), shuffle = (0,1,3,2) = 0x1e
y_128[0] = _mm_shufflelo_epi16(y_128[0],0x1e);
y_128[0] = _mm_shufflehi_epi16(y_128[0],0x1e);
((int16_t*)&y_128[0])[1] = -((int16_t*)&y_128[0])[1];
((int16_t*)&y_128[0])[5] = -((int16_t*)&y_128[0])[5];
y_128[1] = _mm_shufflelo_epi16(y_128[1],0x1e);
y_128[1] = _mm_shufflehi_epi16(y_128[1],0x1e);
((int16_t*)&y_128[1])[1] = -((int16_t*)&y_128[1])[1];
((int16_t*)&y_128[1])[5] = -((int16_t*)&y_128[1])[5];
y_128[2] = _mm_shufflelo_epi16(y_128[2],0x1e);
y_128[2] = _mm_shufflehi_epi16(y_128[2],0x1e);
((int16_t*)&y_128[2])[1] = -((int16_t*)&y_128[2])[1];
((int16_t*)&y_128[2])[5] = -((int16_t*)&y_128[2])[5];
y_128[3] = _mm_shufflelo_epi16(y_128[3],0x1e);
y_128[3] = _mm_shufflehi_epi16(y_128[3],0x1e);
((int16_t*)&y_128[3])[1] = -((int16_t*)&y_128[3])[1];
((int16_t*)&y_128[3])[5] = -((int16_t*)&y_128[3])[5];
}
x_128+=4;
y_128 +=4;
}
_mm_empty();
_m_empty();
return(0);
}
int rotate_cpx_vector2(int16_t *x,
int16_t
*
alpha
,
int16_t
*
alpha
,
int16_t
*
y
,
int16_t
*
y
,
uint32_t
N
,
uint32_t
N
,
uint16_t output_shift,
uint16_t
output_shift
)
uint8_t format)
{
{
// Multiply elementwise two complex vectors of N elements
// multiply a complex vector with a complex value (alpha)
// x - input 1 in the format |Re0 Im0 Re0 Im0|,......,|Re(N-1) Im(N-1) Re(N-1) Im(N-1)|
// stores result in y
// We assume x1 with a dynamic of 15 bit maximum
// N is the number of complex numbers
//
// output_shift reduces the result of the multiplication by this number of bits
// alpha - input 2 in the format |Re0 Im0|
AssertFatal
(
N
%
8
==
0
,
"To be developped"
);
// We assume x2 with a dynamic of 15 bit maximum
const
c16_t
for_re
=
{
alpha
[
0
],
-
alpha
[
1
]};
//
__m256i
const
alpha_for_real
=
_mm256_set1_epi32
(
*
(
uint32_t
*
)
&
for_re
);
// y - output in the format |Re0 Im0 Re0 Im0|,......,|Re(N-1) Im(N-1) Re(N-1) Im(N-1)|
const
c16_t
for_im
=
{
alpha
[
1
],
alpha
[
0
]};
//
__m256i
const
alpha_for_im
=
_mm256_set1_epi32
(
*
(
uint32_t
*
)
&
for_im
);
// N - the size f the vectors (this function does N cpx mpy. WARNING: N>=4;
__m256i
const
perm_mask
=
//
_mm256_set_epi8
(
31
,
30
,
23
,
22
,
29
,
28
,
21
,
20
,
27
,
26
,
19
,
18
,
25
,
24
,
17
,
16
,
// log2_amp - increase the output amplitude by a factor 2^log2_amp (default is 0)
15
,
14
,
7
,
6
,
13
,
12
,
5
,
4
,
11
,
10
,
3
,
2
,
9
,
8
,
1
,
0
);
// WARNING: log2_amp>0 can cause overflow!!
__m256i
*
xd
=
(
__m256i
*
)
x
;
const
__m256i
*
end
=
xd
+
N
/
8
;
uint32_t i; // loop counter
for
(
__m256i
*
yd
=
(
__m256i
*
)
y
;
xd
<
end
;
yd
++
,
xd
++
)
{
const
__m256i
xre
=
_mm256_srai_epi32
(
_mm256_madd_epi16
(
*
xd
,
alpha_for_real
),
register __m128i m0,m1;
output_shift
);
const
__m256i
xim
=
_mm256_srai_epi32
(
_mm256_madd_epi16
(
*
xd
,
alpha_for_im
),
output_shift
);
__m128i *x_128;
// a bit faster than unpacklo+unpackhi+packs
__m128i *y_128;
const
__m256i
tmp
=
_mm256_packs_epi32
(
xre
,
xim
);
*
yd
=
_mm256_shuffle_epi8
(
tmp
,
perm_mask
);
shift = _mm_cvtsi32_si128(output_shift);
x_128 = (__m128i *)&x[0];
if (format==0) { // alpha is in shuffled format for complex multiply
((int16_t *)&alpha_128)[0] = alpha[0];
((int16_t *)&alpha_128)[1] = -alpha[1];
((int16_t *)&alpha_128)[2] = alpha[1];
((int16_t *)&alpha_128)[3] = alpha[0];
((int16_t *)&alpha_128)[4] = alpha[0];
((int16_t *)&alpha_128)[5] = -alpha[1];
((int16_t *)&alpha_128)[6] = alpha[1];
((int16_t *)&alpha_128)[7] = alpha[0];
} else { // input is in shuffled format for complex multiply
((int16_t *)&alpha_128)[0] = alpha[0];
((int16_t *)&alpha_128)[1] = alpha[1];
((int16_t *)&alpha_128)[2] = alpha[0];
((int16_t *)&alpha_128)[3] = alpha[1];
((int16_t *)&alpha_128)[4] = alpha[0];
((int16_t *)&alpha_128)[5] = alpha[1];
((int16_t *)&alpha_128)[6] = alpha[0];
((int16_t *)&alpha_128)[7] = alpha[1];
}
y_128 = (__m128i *)&y[0];
// we compute 4 cpx multiply for each loop
for(i=0; i<(N>>1); i++) {
m0 = _mm_madd_epi16(x_128[i],alpha_128); //pmaddwd_r2r(mm1,mm0); // 1- compute x1[0]*x2[0]
m0 = _mm_sra_epi32(m0,shift); // 1- shift right by shift in order to compensate for the input amplitude
m1=m0;
m1 = _mm_packs_epi32(m1,m0); // 1- pack in a 128 bit register [re im re im]
y_128[i] = _mm_unpacklo_epi32(m1,m1); // 1- pack in a 128 bit register [re im re im]
if (format==1) { // Put output in proper format (Re,-Im,Im,Re), shuffle = (0,1,3,2) = 0x1e
y_128[i] = _mm_shufflelo_epi16(y_128[i],0x1e);
y_128[i] = _mm_shufflehi_epi16(y_128[i],0x1e);
((int16_t*)&y_128[i])[1] = -((int16_t*)&y_128[i])[1];
((int16_t*)&y_128[i])[5] = -((int16_t*)&y_128[i])[5];
}
}
}
_mm_empty();
_m_empty();
return(0);
}
}
*/
#else
void
rotate_cpx_vector
(
int16_t
*
x
,
int
rotate_cpx_vector
(
int16_t
*
x
,
int16_t
*
alpha
,
int16_t
*
alpha
,
int16_t
*
y
,
int16_t
*
y
,
uint32_t
N
,
uint32_t
N
,
...
@@ -439,9 +273,9 @@ int rotate_cpx_vector(int16_t *x,
...
@@ -439,9 +273,9 @@ int rotate_cpx_vector(int16_t *x,
_mm_empty
();
_mm_empty
();
_m_empty
();
_m_empty
();
return
(
0
)
;
return
;
}
}
#endif
/*
/*
int mult_vector32_scalar(int16_t *x1,
int mult_vector32_scalar(int16_t *x1,
int x2,
int x2,
...
...
This diff is collapsed.
Click to expand it.
openair1/PHY/TOOLS/tools_defs.h
View file @
bf219fc2
...
@@ -37,6 +37,7 @@ extern "C" {
...
@@ -37,6 +37,7 @@ extern "C" {
#include <stdint.h>
#include <stdint.h>
#include <assert.h>
#include <assert.h>
#include "PHY/sse_intrin.h"
#include "PHY/sse_intrin.h"
#include "common/utils/assertions.h"
#define CEILIDIV(a,b) ((a+b-1)/b)
#define CEILIDIV(a,b) ((a+b-1)/b)
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
#define ROUNDIDIV(a,b) (((a<<1)+b)/(b<<1))
...
@@ -104,15 +105,6 @@ void multadd_complex_vector_real_scalar(int16_t *x,
...
@@ -104,15 +105,6 @@ void multadd_complex_vector_real_scalar(int16_t *x,
uint8_t
zero_flag
,
uint8_t
zero_flag
,
uint32_t
N
);
uint32_t
N
);
int
rotate_cpx_vector
(
int16_t
*
x
,
int16_t
*
alpha
,
int16_t
*
y
,
uint32_t
N
,
uint16_t
output_shift
);
/*!\fn void init_fft(uint16_t size,uint8_t logsize,uint16_t *rev)
/*!\fn void init_fft(uint16_t size,uint8_t logsize,uint16_t *rev)
\brief Initialize the FFT engine for a given size
\brief Initialize the FFT engine for a given size
@param size Size of the FFT
@param size Size of the FFT
...
@@ -471,7 +463,7 @@ This function performs componentwise multiplication of a vector with a complex s
...
@@ -471,7 +463,7 @@ This function performs componentwise multiplication of a vector with a complex s
The function implemented is : \f$\mathbf{y} = \alpha\mathbf{x}\f$
The function implemented is : \f$\mathbf{y} = \alpha\mathbf{x}\f$
*/
*/
int32_t
rotate_cpx_vector
(
int16_t
*
x
,
void
rotate_cpx_vector
(
int16_t
*
x
,
int16_t
*
alpha
,
int16_t
*
alpha
,
int16_t
*
y
,
int16_t
*
y
,
uint32_t
N
,
uint32_t
N
,
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment