Merge remote-tracking branch 'origin/rlc-optimization' into integration_2024_w44 (!3061)
RLC optimization
Two improvements:
- using functions instead of function pointers which enables inlining
- avoid 1 malloc/free per SDU
Benchmark results:
before:
BM_nr_rlc_am_entity/20000 5036721 ns 5036541 ns 138
BM_nr_rlc_am_entity/20000 5032061 ns 5031849 ns 138
BM_nr_rlc_am_entity/20000 5037071 ns 5037056 ns 138
BM_nr_rlc_am_entity/20000 5035472 ns 5035248 ns 138
BM_nr_rlc_am_entity/20000 5032860 ns 5032681 ns 138
BM_nr_rlc_am_entity/20000_mean 5034837 ns 5034675 ns 5
BM_nr_rlc_am_entity/20000_median 5035472 ns 5035248 ns 5
BM_nr_rlc_am_entity/20000_stddev 2267 ns 2315 ns 5
BM_nr_rlc_am_entity/20000_cv 0.05 % 0.05 % 5
after:
BM_nr_rlc_am_entity/20000 4974403 ns 4974202 ns 140
BM_nr_rlc_am_entity/20000 4976705 ns 4976444 ns 140
BM_nr_rlc_am_entity/20000 5004550 ns 5004508 ns 140
BM_nr_rlc_am_entity/20000 4974652 ns 4974460 ns 140
BM_nr_rlc_am_entity/20000 4976447 ns 4976225 ns 140
BM_nr_rlc_am_entity/20000_mean 4981351 ns 4981168 ns 5
BM_nr_rlc_am_entity/20000_median 4976447 ns 4976225 ns 5
BM_nr_rlc_am_entity/20000_stddev 13009 ns 13087 ns 5
BM_nr_rlc_am_entity/20000_cv 0.26 % 0.26 % 5
This commit is contained in:
@@ -55,7 +55,7 @@ static int modulus_rx(nr_rlc_entity_am_t *entity, int a)
|
||||
return r;
|
||||
}
|
||||
|
||||
static int modulus_tx(nr_rlc_entity_am_t *entity, int a)
|
||||
static inline int modulus_tx(nr_rlc_entity_am_t *entity, int a)
|
||||
{
|
||||
int r = a - entity->tx_next_ack;
|
||||
if (r < 0) r += entity->sn_modulus;
|
||||
@@ -76,12 +76,38 @@ static int sn_compare_rx(void *_entity, int a, int b)
|
||||
return modulus_rx(entity, a) - modulus_rx(entity, b);
|
||||
}
|
||||
|
||||
static int sn_compare_tx(void *_entity, int a, int b)
|
||||
static inline int sn_compare_tx(void *_entity, int a, int b)
|
||||
{
|
||||
nr_rlc_entity_am_t *entity = _entity;
|
||||
return modulus_tx(entity, a) - modulus_tx(entity, b);
|
||||
}
|
||||
|
||||
nr_rlc_sdu_segment_t *nr_rlc_tx_sdu_segment_list_add(nr_rlc_entity_am_t *entity,
|
||||
nr_rlc_sdu_segment_t *list, nr_rlc_sdu_segment_t *sdu_segment)
|
||||
{
|
||||
nr_rlc_sdu_segment_t head;
|
||||
nr_rlc_sdu_segment_t *cur;
|
||||
nr_rlc_sdu_segment_t *prev;
|
||||
|
||||
head.next = list;
|
||||
cur = list;
|
||||
prev = &head;
|
||||
|
||||
/* order is by 'sn', if 'sn' is the same then order is by 'so' */
|
||||
while (cur != NULL) {
|
||||
/* check if 'sdu_segment' is before 'cur' in the list */
|
||||
if (sn_compare_tx(entity, cur->sdu->sn, sdu_segment->sdu->sn) > 0 ||
|
||||
(cur->sdu->sn == sdu_segment->sdu->sn && cur->so > sdu_segment->so)) {
|
||||
break;
|
||||
}
|
||||
prev = cur;
|
||||
cur = cur->next;
|
||||
}
|
||||
prev->next = sdu_segment;
|
||||
sdu_segment->next = cur;
|
||||
return head.next;
|
||||
}
|
||||
|
||||
static int segment_already_received(nr_rlc_entity_am_t *entity,
|
||||
int sn, int so, int size)
|
||||
{
|
||||
@@ -1580,7 +1606,7 @@ static int generate_retx_pdu(nr_rlc_entity_am_t *entity, char *buffer,
|
||||
&& sdu->so > entity->wait_end->so))
|
||||
nr_rlc_sdu_segment_list_append(&entity->wait_list, &entity->wait_end, sdu);
|
||||
else {
|
||||
entity->wait_list = nr_rlc_sdu_segment_list_add(sn_compare_tx, entity,
|
||||
entity->wait_list = nr_rlc_tx_sdu_segment_list_add(entity,
|
||||
entity->wait_list, sdu);
|
||||
if (entity->wait_list->next == NULL)
|
||||
entity->wait_end = entity->wait_list;
|
||||
@@ -1672,7 +1698,7 @@ static int generate_tx_pdu(nr_rlc_entity_am_t *entity, char *buffer, int size)
|
||||
&& sdu->so > entity->wait_end->so))
|
||||
nr_rlc_sdu_segment_list_append(&entity->wait_list, &entity->wait_end, sdu);
|
||||
else {
|
||||
entity->wait_list = nr_rlc_sdu_segment_list_add(sn_compare_tx, entity,
|
||||
entity->wait_list = nr_rlc_tx_sdu_segment_list_add(entity,
|
||||
entity->wait_list, sdu);
|
||||
if (entity->wait_list->next == NULL)
|
||||
entity->wait_end = entity->wait_list;
|
||||
@@ -1881,7 +1907,7 @@ static void check_t_poll_retransmit(nr_rlc_entity_am_t *entity)
|
||||
cur->sdu->sn, cur->so, cur->size, cur->sdu->retx_count);
|
||||
|
||||
/* put in retransmit list */
|
||||
entity->retransmit_list = nr_rlc_sdu_segment_list_add(sn_compare_tx, entity,
|
||||
entity->retransmit_list = nr_rlc_tx_sdu_segment_list_add(entity,
|
||||
entity->retransmit_list, cur);
|
||||
|
||||
cur = entity->wait_list;
|
||||
@@ -2064,3 +2090,4 @@ int nr_rlc_entity_am_available_tx_space(nr_rlc_entity_t *_entity)
|
||||
nr_rlc_entity_am_t *entity = (nr_rlc_entity_am_t *)_entity;
|
||||
return entity->tx_maxsize - entity->tx_size;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,11 @@ nr_rlc_sdu_segment_t *nr_rlc_new_sdu(
|
||||
char *buffer, int size,
|
||||
int upper_layer_id)
|
||||
{
|
||||
nr_rlc_sdu_t *sdu = calloc(1, sizeof(nr_rlc_sdu_t));
|
||||
/* allocate sdu header and data together */
|
||||
nr_rlc_sdu_t *sdu = malloc(sizeof(nr_rlc_sdu_t) + size);
|
||||
/* only memset the header */
|
||||
memset(sdu, 0 , sizeof(*sdu));
|
||||
|
||||
nr_rlc_sdu_segment_t *ret = calloc(1, sizeof(nr_rlc_sdu_segment_t));
|
||||
if (sdu == NULL || ret == NULL)
|
||||
goto oom;
|
||||
@@ -38,9 +42,7 @@ nr_rlc_sdu_segment_t *nr_rlc_new_sdu(
|
||||
sdu->ref_count = 1;
|
||||
sdu->sn = -1; /* set later */
|
||||
sdu->upper_layer_id = upper_layer_id;
|
||||
sdu->data = malloc(size);
|
||||
if (sdu->data == NULL)
|
||||
goto oom;
|
||||
sdu->data = (char*)(sdu + 1);
|
||||
memcpy(sdu->data, buffer, size);
|
||||
sdu->size = size;
|
||||
sdu->retx_count = -1;
|
||||
@@ -64,7 +66,6 @@ int nr_rlc_free_sdu_segment(nr_rlc_sdu_segment_t *sdu)
|
||||
|
||||
sdu->sdu->free_count++;
|
||||
if (sdu->sdu->free_count == sdu->sdu->ref_count) {
|
||||
free(sdu->sdu->data);
|
||||
free(sdu->sdu);
|
||||
ret = 1;
|
||||
}
|
||||
@@ -87,33 +88,6 @@ void nr_rlc_sdu_segment_list_append(nr_rlc_sdu_segment_t **list,
|
||||
*end = sdu;
|
||||
}
|
||||
|
||||
nr_rlc_sdu_segment_t *nr_rlc_sdu_segment_list_add(
|
||||
int (*sn_compare)(void *, int, int), void *sn_compare_data,
|
||||
nr_rlc_sdu_segment_t *list, nr_rlc_sdu_segment_t *sdu_segment)
|
||||
{
|
||||
nr_rlc_sdu_segment_t head;
|
||||
nr_rlc_sdu_segment_t *cur;
|
||||
nr_rlc_sdu_segment_t *prev;
|
||||
|
||||
head.next = list;
|
||||
cur = list;
|
||||
prev = &head;
|
||||
|
||||
/* order is by 'sn', if 'sn' is the same then order is by 'so' */
|
||||
while (cur != NULL) {
|
||||
/* check if 'sdu_segment' is before 'cur' in the list */
|
||||
if (sn_compare(sn_compare_data, cur->sdu->sn, sdu_segment->sdu->sn) > 0 ||
|
||||
(cur->sdu->sn == sdu_segment->sdu->sn && cur->so > sdu_segment->so)) {
|
||||
break;
|
||||
}
|
||||
prev = cur;
|
||||
cur = cur->next;
|
||||
}
|
||||
prev->next = sdu_segment;
|
||||
sdu_segment->next = cur;
|
||||
return head.next;
|
||||
}
|
||||
|
||||
void nr_rlc_free_sdu_segment_list(nr_rlc_sdu_segment_t *l)
|
||||
{
|
||||
nr_rlc_sdu_segment_t *cur;
|
||||
|
||||
@@ -61,9 +61,6 @@ int nr_rlc_free_sdu_segment(nr_rlc_sdu_segment_t *sdu);
|
||||
void nr_rlc_sdu_segment_list_append(nr_rlc_sdu_segment_t **list,
|
||||
nr_rlc_sdu_segment_t **end,
|
||||
nr_rlc_sdu_segment_t *sdu);
|
||||
nr_rlc_sdu_segment_t *nr_rlc_sdu_segment_list_add(
|
||||
int (*sn_compare)(void *, int, int), void *sn_compare_data,
|
||||
nr_rlc_sdu_segment_t *list, nr_rlc_sdu_segment_t *sdu_segment);
|
||||
void nr_rlc_free_sdu_segment_list(nr_rlc_sdu_segment_t *l);
|
||||
|
||||
#endif /* _NR_RLC_SDU_H_ */
|
||||
|
||||
Reference in New Issue
Block a user