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
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
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
OpenXG
OpenXG-RAN
Commits
5ae69ce4
Commit
5ae69ce4
authored
Dec 12, 2024
by
Matthias Mehlhose
Committed by
HHI
Dec 18, 2024
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
refactor: average 64 bit calculations with shift and internal division (SSE and AVX2)
parent
276a1790
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
113 additions
and
102 deletions
+113
-102
openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
+4
-12
openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
+4
-22
openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
+6
-14
openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
+5
-23
openair1/PHY/sse_intrin.h
openair1/PHY/sse_intrin.h
+94
-31
No files found.
openair1/PHY/NR_TRANSPORT/nr_ulsch_demodulation.c
View file @
5ae69ce4
...
...
@@ -209,25 +209,17 @@ static void nr_ulsch_channel_level(int size_est,
uint32_t
len
,
uint8_t
nrOfLayers
)
{
simde__m128i
*
ul_ch128
,
avg128U
;
int16_t
x
=
factor2
(
len
);
int16_t
y
=
(
len
)
>>
x
;
for
(
int
aatx
=
0
;
aatx
<
nrOfLayers
;
aatx
++
)
{
for
(
int
aarx
=
0
;
aarx
<
frame_parms
->
nb_antennas_rx
;
aarx
++
)
{
//clear average level
avg128U
=
simde_mm_setzero_si128
();
ul_ch128
=
(
simde__m128i
*
)
&
ul_ch_estimates_ext
[
aatx
*
frame_parms
->
nb_antennas_rx
+
aarx
][
symbol
*
len
];
for
(
int
i
=
0
;
i
<
len
>>
2
;
i
++
)
{
avg128U
=
simde_mm_add_epi32
(
avg128U
,
simde_mm_srai_epi32
(
simde_mm_madd_epi16
(
ul_ch128
[
i
],
ul_ch128
[
i
]),
x
));
}
simde__m128i
*
ul_ch128
=
(
simde__m128i
*
)
&
ul_ch_estimates_ext
[
aatx
*
frame_parms
->
nb_antennas_rx
+
aarx
][
symbol
*
len
];
int32_t
*
avg32i
=
(
int32_t
*
)
&
avg128U
;
int64_t
avg64
=
(
int64_t
)
avg32i
[
0
]
+
avg32i
[
1
]
+
avg32i
[
2
]
+
avg32i
[
3
]
;
avg
[
aatx
*
frame_parms
->
nb_antennas_rx
+
aarx
]
=
avg64
/
y
;
//compute average level
avg
[
aatx
*
frame_parms
->
nb_antennas_rx
+
aarx
]
=
simde_mm_average
(
ul_ch128
,
len
,
x
,
y
)
;
//LOG_D(PHY, "Channel level: %d\n", avg[aatx * frame_parms->nb_antennas_rx + aarx])
;
}
}
...
...
openair1/PHY/NR_UE_TRANSPORT/dci_nr.c
View file @
5ae69ce4
...
...
@@ -226,30 +226,12 @@ void nr_pdcch_channel_level(int32_t rx_size,
int
nb_rb
)
{
for
(
int
aarx
=
0
;
aarx
<
frame_parms
->
nb_antennas_rx
;
aarx
++
)
{
//clear average level
simde__m128i
avg128P
=
simde_mm_setzero_si128
();
simde__m128i
*
dl_ch128
=
(
simde__m128i
*
)
&
dl_ch_estimates_ext
[
aarx
][
symbol
*
nb_rb
*
12
];
for
(
int
rb
=
0
;
rb
<
(
nb_rb
*
3
)
>>
2
;
rb
++
)
{
avg128P
=
simde_mm_add_epi32
(
avg128P
,
simde_mm_madd_epi16
(
dl_ch128
[
0
],
dl_ch128
[
0
]));
avg128P
=
simde_mm_add_epi32
(
avg128P
,
simde_mm_madd_epi16
(
dl_ch128
[
1
],
dl_ch128
[
1
]));
avg128P
=
simde_mm_add_epi32
(
avg128P
,
simde_mm_madd_epi16
(
dl_ch128
[
2
],
dl_ch128
[
2
]));
// for (int i=0;i<24;i+=2) printf("pdcch channel re %d (%d,%d)\n",(rb*12)+(i>>1),((int16_t*)dl_ch128)[i],((int16_t*)dl_ch128)[i+1]);
dl_ch128
+=
3
;
/*
if (rb==0) {
print_shorts("dl_ch128",&dl_ch128[0]);
print_shorts("dl_ch128",&dl_ch128[1]);
print_shorts("dl_ch128",&dl_ch128[2]);
}
*/
}
simde__m128i
*
dl_ch128
=
(
simde__m128i
*
)
&
dl_ch_estimates_ext
[
aarx
][
symbol
*
nb_rb
*
12
];
DevAssert
(
nb_rb
);
avg
[
aarx
]
=
0
;
for
(
int
i
=
0
;
i
<
4
;
i
++
)
avg
[
aarx
]
+=
((
int32_t
*
)
&
avg128P
)[
i
]
/
(
nb_rb
*
9
);
LOG_DDD
(
"Channel level : %d
\n
"
,
avg
[
aarx
]);
//compute average level
avg
[
aarx
]
=
simde_mm_average
(
dl_ch128
,
nb_rb
*
12
,
0
,
nb_rb
*
12
);
//LOG_DDD("Channel level : %d\n", avg[aarx]);
}
}
...
...
openair1/PHY/NR_UE_TRANSPORT/nr_dlsch_demodulation.c
View file @
5ae69ce4
...
...
@@ -1098,28 +1098,20 @@ void nr_dlsch_channel_level(uint32_t rx_size_symbol,
int32_t
avg
[
MAX_ANT
][
MAX_ANT
],
uint32_t
len
)
{
simde__m128i
*
dl_ch128
,
avg128D
;
//nb_rb*nre = y * 2^x
int16_t
x
=
factor2
(
len
);
int16_t
y
=
(
len
)
>>
x
;
uint32_t
nb_rb_0
=
len
/
NR_NB_SC_PER_RB
+
((
len
%
NR_NB_SC_PER_RB
)
?
1
:
0
);
LOG_D
(
NR_PHY
,
"nb_rb_0 %d len %d = %d * 2^(%d)
\n
"
,
nb_rb_0
,
len
,
y
,
x
);
for
(
int
aatx
=
0
;
aatx
<
n_tx
;
aatx
++
)
{
for
(
int
aarx
=
0
;
aarx
<
n_rx
;
aarx
++
)
{
//clear average level
avg128D
=
simde_mm_setzero_si128
();
dl_ch128
=
(
simde__m128i
*
)
dl_ch_estimates_ext
[(
aatx
*
n_rx
)
+
aarx
];
simde__m128i
*
dl_ch128
=
(
simde__m128i
*
)
dl_ch_estimates_ext
[(
aatx
*
n_rx
)
+
aarx
];
for
(
int
rb
=
0
;
rb
<
nb_rb_0
;
rb
++
)
{
avg128D
=
simde_mm_add_epi32
(
avg128D
,
simde_mm_srai_epi32
(
simde_mm_madd_epi16
(
dl_ch128
[
0
],
dl_ch128
[
0
]),
x
));
avg128D
=
simde_mm_add_epi32
(
avg128D
,
simde_mm_srai_epi32
(
simde_mm_madd_epi16
(
dl_ch128
[
1
],
dl_ch128
[
1
]),
x
));
avg128D
=
simde_mm_add_epi32
(
avg128D
,
simde_mm_srai_epi32
(
simde_mm_madd_epi16
(
dl_ch128
[
2
],
dl_ch128
[
2
]),
x
));
dl_ch128
+=
3
;
}
int32_t
*
tmp
=
(
int32_t
*
)
&
avg128D
;
avg
[
aatx
][
aarx
]
=
((
int64_t
)
tmp
[
0
]
+
tmp
[
1
]
+
tmp
[
2
]
+
tmp
[
3
])
/
y
;
LOG_D
(
PHY
,
"Channel level: %d
\n
"
,
avg
[
aatx
][
aarx
]);
//compute average level
avg
[
aatx
][
aarx
]
=
simde_mm_average
(
dl_ch128
,
nb_rb_0
*
12
,
x
,
y
);
//LOG_D(PHY, "Channel level: %d\n", avg[aatx][aarx]);
}
}
}
...
...
openair1/PHY/NR_UE_TRANSPORT/nr_pbch.c
View file @
5ae69ce4
...
...
@@ -208,32 +208,14 @@ int nr_pbch_channel_level(struct complex16 dl_ch_estimates_ext[][PBCH_MAX_RE_PER
const
NR_DL_FRAME_PARMS
*
frame_parms
,
int
nb_re
)
{
int16_t
nb_rb
=
nb_re
/
12
;
simde__m128i
avg128
;
simde__m128i
*
dl_ch128
;
int
avg2
=
0
;
int32_t
avg2
=
0
;
for
(
int
aarx
=
0
;
aarx
<
frame_parms
->
nb_antennas_rx
;
aarx
++
)
{
//clear average level
avg128
=
simde_mm_setzero_si128
();
dl_ch128
=
(
simde__m128i
*
)
dl_ch_estimates_ext
[
aarx
];
for
(
int
rb
=
0
;
rb
<
nb_rb
;
rb
++
)
{
avg128
=
simde_mm_add_epi32
(
avg128
,
simde_mm_madd_epi16
(
dl_ch128
[
0
],
dl_ch128
[
0
]));
avg128
=
simde_mm_add_epi32
(
avg128
,
simde_mm_madd_epi16
(
dl_ch128
[
1
],
dl_ch128
[
1
]));
avg128
=
simde_mm_add_epi32
(
avg128
,
simde_mm_madd_epi16
(
dl_ch128
[
2
],
dl_ch128
[
2
]));
dl_ch128
+=
3
;
/*
if (rb==0) {
print_shorts("dl_ch128",&dl_ch128[0]);
print_shorts("dl_ch128",&dl_ch128[1]);
print_shorts("dl_ch128",&dl_ch128[2]);
}*/
}
int
avg1
=
0
;
for
(
int
i
=
0
;
i
<
4
;
i
++
)
avg1
+=
((
int
*
)
&
avg128
)[
i
]
/
(
nb_rb
*
12
);
simde__m128i
*
dl_ch128
=
(
simde__m128i
*
)
dl_ch_estimates_ext
[
aarx
];
//compute average level
int32_t
avg1
=
simde_mm_average
(
dl_ch128
,
nb_re
,
0
,
nb_re
);
if
(
avg1
>
avg2
)
avg2
=
avg1
;
...
...
openair1/PHY/sse_intrin.h
View file @
5ae69ce4
...
...
@@ -49,13 +49,6 @@
#define SSE_INTRIN_H
#include <simde/x86/mmx.h>
#include <simde/x86/sse.h>
#include <simde/x86/sse2.h>
#include <simde/x86/sse3.h>
#include <simde/x86/ssse3.h>
#include <simde/x86/sse4.1.h>
#include <simde/x86/sse4.2.h>
#include <simde/x86/avx2.h>
#include <simde/x86/fma.h>
#if defined(__x86_64) || defined(__i386__)
...
...
@@ -81,31 +74,101 @@
* OAI specific
*/
static
const
short
minusConjug128
[
8
]
__attribute__
((
aligned
(
16
)))
=
{
-
1
,
1
,
-
1
,
1
,
-
1
,
1
,
-
1
,
1
};
static
inline
simde__m128i
mulByConjugate128
(
simde__m128i
*
a
,
simde__m128i
*
b
,
int8_t
output_shift
)
{
simde__m128i
realPart
=
simde_mm_madd_epi16
(
*
a
,
*
b
);
realPart
=
simde_mm_srai_epi32
(
realPart
,
output_shift
);
simde__m128i
imagPart
=
simde_mm_shufflelo_epi16
(
*
b
,
SIMDE_MM_SHUFFLE
(
2
,
3
,
0
,
1
));
imagPart
=
simde_mm_shufflehi_epi16
(
imagPart
,
SIMDE_MM_SHUFFLE
(
2
,
3
,
0
,
1
));
imagPart
=
simde_mm_sign_epi16
(
imagPart
,
*
(
simde__m128i
*
)
minusConjug128
);
imagPart
=
simde_mm_madd_epi16
(
imagPart
,
*
a
);
imagPart
=
simde_mm_srai_epi32
(
imagPart
,
output_shift
);
simde__m128i
lowPart
=
simde_mm_unpacklo_epi32
(
realPart
,
imagPart
);
simde__m128i
highPart
=
simde_mm_unpackhi_epi32
(
realPart
,
imagPart
);
return
(
simde_mm_packs_epi32
(
lowPart
,
highPart
));
static
const
short
minusConjug128
[
8
]
__attribute__
((
aligned
(
16
)))
=
{
-
1
,
1
,
-
1
,
1
,
-
1
,
1
,
-
1
,
1
};
static
inline
simde__m128i
mulByConjugate128
(
simde__m128i
*
a
,
simde__m128i
*
b
,
int8_t
output_shift
)
{
simde__m128i
realPart
=
simde_mm_madd_epi16
(
*
a
,
*
b
);
realPart
=
simde_mm_srai_epi32
(
realPart
,
output_shift
);
simde__m128i
imagPart
=
simde_mm_shufflelo_epi16
(
*
b
,
SIMDE_MM_SHUFFLE
(
2
,
3
,
0
,
1
));
imagPart
=
simde_mm_shufflehi_epi16
(
imagPart
,
SIMDE_MM_SHUFFLE
(
2
,
3
,
0
,
1
));
imagPart
=
simde_mm_sign_epi16
(
imagPart
,
*
(
simde__m128i
*
)
minusConjug128
);
imagPart
=
simde_mm_madd_epi16
(
imagPart
,
*
a
);
imagPart
=
simde_mm_srai_epi32
(
imagPart
,
output_shift
);
simde__m128i
lowPart
=
simde_mm_unpacklo_epi32
(
realPart
,
imagPart
);
simde__m128i
highPart
=
simde_mm_unpackhi_epi32
(
realPart
,
imagPart
);
return
(
simde_mm_packs_epi32
(
lowPart
,
highPart
));
}
#define displaySamples128(vect) {\
simde__m128i x=vect; \
printf("vector: %s = (%hd,%hd) (%hd,%hd) (%hd,%hd) (%hd,%hd)\n", #vect, \
simde_mm_extract_epi16(x,0), \
simde_mm_extract_epi16(x,1),\
simde_mm_extract_epi16(x,2),\
simde_mm_extract_epi16(x,3),\
simde_mm_extract_epi16(x,4),\
simde_mm_extract_epi16(x,5),\
simde_mm_extract_epi16(x,6),\
simde_mm_extract_epi16(x,7));\
#define displaySamples128(vect) \
{ \
simde__m128i x = vect; \
printf("vector: %s = (%hd,%hd) (%hd,%hd) (%hd,%hd) (%hd,%hd)\n", \
#vect, \
simde_mm_extract_epi16(x, 0), \
simde_mm_extract_epi16(x, 1), \
simde_mm_extract_epi16(x, 2), \
simde_mm_extract_epi16(x, 3), \
simde_mm_extract_epi16(x, 4), \
simde_mm_extract_epi16(x, 5), \
simde_mm_extract_epi16(x, 6), \
simde_mm_extract_epi16(x, 7)); \
}
__attribute__
((
always_inline
))
static
inline
int64_t
simde_mm_average_sse
(
simde__m128i
*
a
,
int
length
,
int
shift
)
{
// compute average level with shift (64-bit verstion)
simde__m128i
avg128
=
simde_mm_setzero_si128
();
for
(
int
i
=
0
;
i
<
length
>>
2
;
i
++
)
{
const
simde__m128i
in1
=
a
[
i
];
avg128
=
simde_mm_add_epi32
(
avg128
,
simde_mm_srai_epi32
(
simde_mm_madd_epi16
(
in1
,
in1
),
shift
));
}
// Horizontally add pairs
// 1st [A + C, B + D]
simde__m128i
sum_pairs
=
simde_mm_add_epi64
(
simde_mm_unpacklo_epi32
(
avg128
,
simde_mm_setzero_si128
()),
// [A, B] → [A, 0, B, 0]
simde_mm_unpackhi_epi32
(
avg128
,
simde_mm_setzero_si128
())
// [C, D] → [C, 0, D, 0]
);
// 2nd [A + B + C + D, ...]
simde__m128i
total_sum
=
simde_mm_add_epi64
(
sum_pairs
,
simde_mm_shuffle_epi32
(
sum_pairs
,
SIMDE_MM_SHUFFLE
(
1
,
0
,
3
,
2
)));
// Extract horizontal sum as a scalar int64_t result
return
simde_mm_cvtsi128_si64
(
total_sum
);
}
__attribute__
((
always_inline
))
static
inline
int64_t
simde_mm_average_avx2
(
simde__m256i
*
a
,
int
length
,
int
shift
)
{
simde__m256i
avg256
=
simde_mm256_setzero_si256
();
for
(
int
i
=
0
;
i
<
length
>>
3
;
i
++
)
{
const
simde__m256i
in1
=
simde_mm256_loadu_si256
(
&
a
[
i
]);
// unaligned load
avg256
=
simde_mm256_add_epi32
(
avg256
,
simde_mm256_srai_epi32
(
simde_mm256_madd_epi16
(
in1
,
in1
),
shift
));
}
// Split the 256-bit vector into two 128-bit halves and convert to 64-bit
// [A + E, B + F, C + G, D + H]
simde__m256i
sum_pairs
=
simde_mm256_add_epi64
(
simde_mm256_cvtepi32_epi64
(
simde_mm256_castsi256_si128
(
avg256
)),
// [A, B, C, D] → [A, 0, B, 0, C, 0, D, 0]
simde_mm256_cvtepi32_epi64
(
simde_mm256_extracti128_si256
(
avg256
,
1
))
// [E, F, G, H] → [E, 0, F, 0, G, 0, H, 0]
);
// Horizontal sum within the 256-bit vector
// [A + E + B + F, C + G + D + H]
simde__m128i
total_sum
=
simde_mm_add_epi64
(
simde_mm256_castsi256_si128
(
sum_pairs
),
simde_mm256_extracti128_si256
(
sum_pairs
,
1
));
// [A + E + B + F + C + G + D + H, ...]
total_sum
=
simde_mm_add_epi64
(
total_sum
,
simde_mm_shuffle_epi32
(
total_sum
,
SIMDE_MM_SHUFFLE
(
1
,
0
,
3
,
2
)));
// Extract horizontal sum as a scalar int64_t result
return
simde_mm_cvtsi128_si64
(
total_sum
);
}
__attribute__
((
always_inline
))
static
inline
int32_t
simde_mm_average
(
simde__m128i
*
a
,
int
length
,
int
shift
,
int16_t
scale
)
{
int64_t
avg
=
0
;
#if defined(__x86_64__) || defined(__i386__)
if
(
__builtin_cpu_supports
(
"avx2"
))
{
avg
+=
simde_mm_average_avx2
((
simde__m256i
*
)
a
,
length
,
shift
);
// tail processing by SSE
a
+=
((
length
&
~
7
)
>>
2
);
length
-=
(
length
&
~
7
);
}
#endif
avg
+=
simde_mm_average_sse
(
a
,
length
,
shift
);
return
(
uint32_t
)(
avg
/
scale
);
}
#endif // SSE_INTRIN_H
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