Commit b5aad595 authored by Bartosz Podrygajlo's avatar Bartosz Podrygajlo

vrtsim: rewrite sample history

Limit sample history to 256 samples and copy it into each channel modelling
task instead of relying on globally available buffer. This simplifies the code
and addressing into the saved samples buffer as well as enabling further
optimizations without sacrificing thread safety.
parent 479be40b
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
typedef enum { ROLE_SERVER = 1, ROLE_CLIENT } role; typedef enum { ROLE_SERVER = 1, ROLE_CLIENT } role;
#define MAX_NUM_ANTENNAS_TX 4 #define MAX_NUM_ANTENNAS_TX 4
#define MAX_CHANNEL_LENGTH (1 << 20) #define SAVED_SAMPLES_LEN 256
#define ROLE_CLIENT_STRING "client" #define ROLE_CLIENT_STRING "client"
#define ROLE_SERVER_STRING "server" #define ROLE_SERVER_STRING "server"
...@@ -125,9 +125,6 @@ typedef struct { ...@@ -125,9 +125,6 @@ typedef struct {
int client_num_rx_antennas; int client_num_rx_antennas;
} vrtsim_state_t; } vrtsim_state_t;
// Sample history for channel impulse response
static c16_t saved_samples[MAX_NUM_ANTENNAS_TX][MAX_CHANNEL_LENGTH] __attribute__((aligned(32))) = {0};
static void histogram_add(histogram_t *histogram, double diff) static void histogram_add(histogram_t *histogram, double diff)
{ {
histogram->num_samples++; histogram->num_samples++;
...@@ -375,6 +372,7 @@ typedef struct { ...@@ -375,6 +372,7 @@ typedef struct {
int nbAnt; int nbAnt;
int flags; int flags;
int aarx; int aarx;
c16_t saved_samples[MAX_NUM_ANTENNAS_TX][SAVED_SAMPLES_LEN];
} channel_modelling_args_t; } channel_modelling_args_t;
static void perform_channel_modelling(void *arg) static void perform_channel_modelling(void *arg)
...@@ -418,14 +416,13 @@ static void perform_channel_modelling(void *arg) ...@@ -418,14 +416,13 @@ static void perform_channel_modelling(void *arg)
} }
for (int aatx = 0; aatx < nb_tx_ant; aatx++) { for (int aatx = 0; aatx < nb_tx_ant; aatx++) {
c16_t *previous_samples = saved_samples[aatx];
for (int i = 0; i < nsamps; i++) { for (int i = 0; i < nsamps; i++) {
cf_t *impulse_response = channel_impulse_response_p[aatx]; cf_t *impulse_response = channel_impulse_response_p[aatx];
for (int l = 0; l < channel_desc->channel_length; l++) { for (int l = 0; l < channel_desc->channel_length; l++) {
int idx = i - l; int idx = i - l;
// TODO: Use AVX2 for this // TODO: Use AVX2 for this
c16_t tx_input = idx >= 0 ? input_samples[aatx][idx] c16_t tx_input = idx >= 0 ? input_samples[aatx][idx]
: previous_samples[(channel_modelling_args->timestamp + i + idx) % MAX_CHANNEL_LENGTH]; : channel_modelling_args->saved_samples[aatx][SAVED_SAMPLES_LEN + idx];
samples[i].r += tx_input.r * impulse_response[l].r - tx_input.i * impulse_response[l].i; samples[i].r += tx_input.r * impulse_response[l].r - tx_input.i * impulse_response[l].i;
samples[i].i += tx_input.i * impulse_response[l].r + tx_input.r * impulse_response[l].i; samples[i].i += tx_input.i * impulse_response[l].r + tx_input.r * impulse_response[l].i;
} }
...@@ -469,6 +466,11 @@ static int vrtsim_write_with_chanmod(vrtsim_state_t *vrtsim_state, ...@@ -469,6 +466,11 @@ static int vrtsim_write_with_chanmod(vrtsim_state_t *vrtsim_state,
int nbAnt, int nbAnt,
int flags) int flags)
{ {
// Sample history for channel impulse response
static c16_t saved_samples[MAX_NUM_ANTENNAS_TX][SAVED_SAMPLES_LEN] __attribute__((aligned(32))) = {0};
// Indicates what samples are saves in saved_samples
static openair0_timestamp last_timestamp = 0;
AssertFatal(nbAnt < MAX_NUM_ANTENNAS_TX, "Number of antennas %d exceeds maximum %d\n", nbAnt, MAX_NUM_ANTENNAS_TX); AssertFatal(nbAnt < MAX_NUM_ANTENNAS_TX, "Number of antennas %d exceeds maximum %d\n", nbAnt, MAX_NUM_ANTENNAS_TX);
for (int aarx = 0; aarx < vrtsim_state->peer_info.num_rx_antennas; aarx++) { for (int aarx = 0; aarx < vrtsim_state->peer_info.num_rx_antennas; aarx++) {
notifiedFIFO_elt_t *task = newNotifiedFIFO_elt(sizeof(channel_modelling_args_t), 0, NULL, perform_channel_modelling); notifiedFIFO_elt_t *task = newNotifiedFIFO_elt(sizeof(channel_modelling_args_t), 0, NULL, perform_channel_modelling);
...@@ -482,25 +484,40 @@ static int vrtsim_write_with_chanmod(vrtsim_state_t *vrtsim_state, ...@@ -482,25 +484,40 @@ static int vrtsim_write_with_chanmod(vrtsim_state_t *vrtsim_state,
for (int i = 0; i < nbAnt; i++) { for (int i = 0; i < nbAnt; i++) {
args->samples[i] = samplesVoid[i]; args->samples[i] = samplesVoid[i];
} }
// Fill in saved_samples
size_t gap_samples = timestamp - last_timestamp;
if (gap_samples > 0) {
size_t gap_samples_needed = min(SAVED_SAMPLES_LEN, gap_samples);
for (int aatx = 0; aatx < nbAnt; aatx++) {
memset(&args->saved_samples[aatx][SAVED_SAMPLES_LEN - gap_samples_needed], 0, sizeof(c16_t) * gap_samples_needed);
if (gap_samples < SAVED_SAMPLES_LEN) {
size_t samples_from_saved = SAVED_SAMPLES_LEN - gap_samples_needed;
memcpy(&args->saved_samples[aatx][0], &saved_samples[aatx][SAVED_SAMPLES_LEN - samples_from_saved], sizeof(c16_t) * samples_from_saved);
}
}
} else {
for (int aatx = 0; aatx < nbAnt; aatx++)
memcpy(&args->saved_samples[aatx][0], saved_samples[aatx], sizeof(c16_t) * SAVED_SAMPLES_LEN);
}
memcpy(args->saved_samples, saved_samples, sizeof(saved_samples));
pushNotifiedFIFO(&vrtsim_state->channel_modelling_actors[aarx].fifo, task); pushNotifiedFIFO(&vrtsim_state->channel_modelling_actors[aarx].fifo, task);
} }
int start_index = timestamp % MAX_CHANNEL_LENGTH;
int end_index = min(start_index + nsamps, MAX_CHANNEL_LENGTH);
int cp_nsamps = end_index - start_index;
for (int aatx = 0; aatx < nbAnt; aatx++) {
c16_t *samples = (c16_t *)samplesVoid[aatx];
memcpy(&saved_samples[aatx][start_index], &samples[0], sizeof(c16_t) * cp_nsamps);
}
if (end_index < start_index + nsamps) { // Save samples for next round
// wrap around condition, write at beginning of buffer if (nsamps < SAVED_SAMPLES_LEN) {
cp_nsamps = nsamps - cp_nsamps; // remaining samples
start_index = 0;
for (int aatx = 0; aatx < nbAnt; aatx++) { for (int aatx = 0; aatx < nbAnt; aatx++) {
c16_t *samples = (c16_t *)samplesVoid[aatx]; memmove(&saved_samples[aatx][0], &saved_samples[aatx][nsamps], sizeof(c16_t) * (SAVED_SAMPLES_LEN - nsamps));
memcpy(&saved_samples[aatx][start_index], &samples[0], sizeof(c16_t) * cp_nsamps); memcpy(&saved_samples[aatx][SAVED_SAMPLES_LEN - nsamps], samplesVoid[aatx], sizeof(c16_t) * nsamps);
}
} else {
for (int aatx = 0; aatx < nbAnt; aatx++) {
c16_t* samples = (c16_t*)samplesVoid[aatx];
memcpy(saved_samples[aatx], &samples[nsamps - SAVED_SAMPLES_LEN], sizeof(c16_t) * (SAVED_SAMPLES_LEN));
} }
} }
last_timestamp = timestamp + nsamps;
return nsamps; return nsamps;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment