mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 04:30:28 +00:00
use SIMD to speed up nr_fo_compensation()
This commit is contained in:
@@ -459,10 +459,34 @@ void nr_fo_compensation(double fo_Hz, int samples_per_ms, int sample_offset, c16
|
||||
const double phase_inc = -fo_Hz / (samples_per_ms * 1000);
|
||||
double phase = sample_offset * phase_inc;
|
||||
phase -= (int)phase;
|
||||
for (int i = 0; i < size; i++) {
|
||||
c16_t rot = get_sin_cos(phase);
|
||||
*rxdata_ptr = c16mulShift(*rxdata_ptr, rot, 14);
|
||||
rxdata_ptr++;
|
||||
#if 1
|
||||
// The bottleneck is the calculation of the complex rotation values using get_sin_cos().
|
||||
// This code path does not compute these values for the complete OFDM symbol, but only for a smaller CHUNK size.
|
||||
// After applying the rotation to a CHUNK size of the output, these rotation values are efficiently rotated further by `rot_vec`.
|
||||
// Unfortunately, this propagates small errors from one chunk to the next.
|
||||
// Therefore, there is a tradeoff between speed (better with small CHUNK sizes) and accuracy (better with large CHUNK sizes).
|
||||
#define CHUNK 128
|
||||
c16_t rot[CHUNK] __attribute__((aligned(32)));
|
||||
for (int i = 0; i < CHUNK; i++) {
|
||||
rot[i] = get_sin_cos(phase);
|
||||
phase += phase_inc;
|
||||
}
|
||||
const c16_t rot_vec = get_sin_cos(CHUNK * phase_inc);
|
||||
while (size > CHUNK) {
|
||||
mult_complex_vectors(rxdata_ptr, rot, rxdata_ptr, CHUNK, 14);
|
||||
rxdata_ptr += CHUNK;
|
||||
rotate_cpx_vector(rot, &rot_vec, rot, CHUNK, 14);
|
||||
size -= CHUNK;
|
||||
}
|
||||
mult_complex_vectors(rxdata_ptr, rot, rxdata_ptr, size, 14);
|
||||
#else
|
||||
// This code path computes the complex rotation values for the complete OFDM symbol using get_sin_cos().
|
||||
// This is more accurate, but also slower than the code path above.
|
||||
c16_t rot[size] __attribute__((aligned(32)));
|
||||
for (int i = 0; i < size; i++) {
|
||||
rot[i] = get_sin_cos(phase);
|
||||
phase += phase_inc;
|
||||
}
|
||||
mult_complex_vectors(rxdata_ptr, rot, rxdata_ptr, size, 14);
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user