mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 04:30:28 +00:00
Compare commits
9 Commits
develop
...
more_time_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c89dee6382 | ||
|
|
0b97ef2057 | ||
|
|
f6ee85a014 | ||
|
|
cb1d707f87 | ||
|
|
362445a058 | ||
|
|
e1f477e1f9 | ||
|
|
10bb591f29 | ||
|
|
84e3a647c6 | ||
|
|
56c6fcdd1c |
@@ -26,6 +26,7 @@ It is defined in include file [ common/config/config_paramdesc.h ](https://gitla
|
||||
| `PARAMFLAG_NOFREE` | The end_configmodule API won't free the memory which has been possibly allocated to store the value of the parameter.| I |
|
||||
| `PARAMFLAG_BOOL` | Parameter is a boolean, it can be specified without a value to set it to true | I |
|
||||
| `PARAMFLAG_CMDLINE_NOPREFIXENABLED` | parameter can be specified without the prefix on the command line. Must be used with care, carefuly checking unicity, especially for short parameter names | I |
|
||||
| `PARAMFLAG_VALUE_OPTIONAL` | Parameter can be specified with a value or without a value to set it to 1 | I |
|
||||
| `PARAMFLAG_MALLOCINCONFIG` | Memory for the parameter value has been allocated by the configuration module |O |
|
||||
| `PARAMFLAG_PARAMSET` | Parameter value has been explicitely set, as the parameter was specified either on the command line or the config source | O |
|
||||
| `PARAMFLAG_PARAMSETDEF` | Parameter value has been set to it's default | O |
|
||||
|
||||
@@ -57,7 +57,7 @@ static int processoption(configmodule_interface_t *cfg, paramdef_t *cfgoptions,
|
||||
char defbool[2]="1";
|
||||
|
||||
if ( value == NULL) {
|
||||
if( (cfgoptions->paramflags &PARAMFLAG_BOOL) == 0 ) { /* not a boolean, argument required */
|
||||
if( (cfgoptions->paramflags & (PARAMFLAG_BOOL | PARAMFLAG_VALUE_OPTIONAL)) == 0 ) { /* not a boolean, argument required */
|
||||
CONFIG_PRINTF_ERROR("[CONFIG] command line, option %s requires an argument\n",cfgoptions->optname);
|
||||
AssertFatal(false, "[CONFIG] command line, requires an argument\n");
|
||||
} else { /* boolean value option without argument, set value to true*/
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
#define PARAMFLAG_NOFREE (1 << 3) // don't free parameter in end function
|
||||
#define PARAMFLAG_BOOL (1 << 4) // integer param can be 0 or 1
|
||||
#define PARAMFLAG_CMDLINE_NOPREFIXENABLED (1 << 5) // on the command line, allow a parameter to be specified without the prefix
|
||||
#define PARAMFLAG_CMDLINEONLY (1 << 6) // this parameter cannot be specified in config file
|
||||
#define PARAMFLAG_CMDLINEONLY (1 << 6) // this parameter cannot be specified in config file
|
||||
#define PARAMFLAG_VALUE_OPTIONAL (1 << 7) // integer param is 1 if no value provided
|
||||
|
||||
/* Flags used by config modules to return info to calling modules and/or to for internal usage*/
|
||||
#define PARAMFLAG_MALLOCINCONFIG (1 << 15) // parameter allocated in config module
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
#define DICHOTOMY
|
||||
#include <stdio.h>
|
||||
#include "time_meas.h"
|
||||
#include <math.h>
|
||||
@@ -34,6 +35,11 @@ double get_cpu_freq_GHz(void)
|
||||
}
|
||||
|
||||
|
||||
static double StdDev(time_stats_t *ptr)
|
||||
{
|
||||
return sqrt((double)ptr->diff_square * 1e-6 / ptr->trials - pow((double)ptr->diff / ptr->trials / 1000, 2));
|
||||
}
|
||||
|
||||
|
||||
void print_meas_now(time_stats_t *ts, const char *name, FILE *file_name)
|
||||
{
|
||||
@@ -92,6 +98,45 @@ void print_meas(time_stats_t *ts,
|
||||
}
|
||||
}
|
||||
|
||||
size_t print_meas_log_header(time_stats_t *total_exec_time,
|
||||
time_stats_t *sf_exec_time,
|
||||
char *output,
|
||||
size_t outputlen)
|
||||
{
|
||||
const char *begin = output;
|
||||
const char *end = output + outputlen;
|
||||
|
||||
if ((total_exec_time == NULL) || (sf_exec_time== NULL))
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
"%25s %18s %18s %18s %15s %18s %18s %18s %18s %18s %18s %9s %6f\n",
|
||||
"Name",
|
||||
"Total",
|
||||
"Max",
|
||||
"Std",
|
||||
"Num Trials",
|
||||
"min",
|
||||
"d1",
|
||||
"q1",
|
||||
"median",
|
||||
"q3",
|
||||
"d9",
|
||||
"CPU_F_GHz",
|
||||
cpu_freq_GHz);
|
||||
else
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
"%25s %18s %18s %15s %9s %6f\n",
|
||||
"Name",
|
||||
"Total",
|
||||
"Average/Frame",
|
||||
"Trials",
|
||||
"CPU_F_GHz",
|
||||
cpu_freq_GHz);
|
||||
|
||||
return output - begin;
|
||||
}
|
||||
|
||||
size_t print_meas_log(time_stats_t *ts,
|
||||
const char *name,
|
||||
time_stats_t *total_exec_time,
|
||||
@@ -101,46 +146,38 @@ size_t print_meas_log(time_stats_t *ts,
|
||||
{
|
||||
const char *begin = output;
|
||||
const char *end = output + outputlen;
|
||||
static int first_time = 0;
|
||||
static double cpu_freq_GHz = 0.0;
|
||||
|
||||
if (cpu_freq_GHz == 0.0)
|
||||
cpu_freq_GHz = get_cpu_freq_GHz();
|
||||
|
||||
if (first_time == 0) {
|
||||
first_time=1;
|
||||
|
||||
if ((total_exec_time == NULL) || (sf_exec_time== NULL))
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
"%25s %25s %25s %25s %25s %6f\n",
|
||||
"Name",
|
||||
"Total",
|
||||
"Per Trials",
|
||||
"Num Trials",
|
||||
"CPU_F_GHz",
|
||||
cpu_freq_GHz);
|
||||
else
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
"%25s %25s %25s %20s %15s %6f\n",
|
||||
"Name",
|
||||
"Total",
|
||||
"Average/Frame",
|
||||
"Trials",
|
||||
"CPU_F_GHz",
|
||||
cpu_freq_GHz);
|
||||
}
|
||||
|
||||
if (ts->trials>0) {
|
||||
if ((total_exec_time == NULL) || (sf_exec_time== NULL)) {
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
"%25s: %15.3f us; %15d; %15.3f us;\n",
|
||||
name,
|
||||
ts->diff / ts->trials / cpu_freq_GHz / 1000.0,
|
||||
ts->trials,
|
||||
ts->max / cpu_freq_GHz / 1000.0);
|
||||
if (is_enabled_time_stats_sorted_list(&ts->time_stats_sorted_list)) {
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
"%25s: %15.3f us; %15.3f us; %15.3f us; %15d; %15.3f us; %15.3f us; %15.3f us; %15.3f us; %15.3f us; %15.3f us;\n",
|
||||
name,
|
||||
ts->diff / ts->trials / 1000.0,
|
||||
ts->max / 1000.0,
|
||||
StdDev(ts),
|
||||
ts->trials,
|
||||
get_min(&ts->time_stats_sorted_list) / 1000.0,
|
||||
get_d1(&ts->time_stats_sorted_list) / 1000.0,
|
||||
get_q1(&ts->time_stats_sorted_list) / 1000.0,
|
||||
get_median(&ts->time_stats_sorted_list) / 1000.0,
|
||||
get_q3(&ts->time_stats_sorted_list) / 1000.0,
|
||||
get_d9(&ts->time_stats_sorted_list) / 1000.0);
|
||||
} else {
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
"%25s: %15.3f us; %15.3f us; %15.3f us; %15d;\n",
|
||||
name,
|
||||
ts->diff / ts->trials / 1000.0,
|
||||
ts->max / 1000.0,
|
||||
StdDev(ts),
|
||||
ts->trials);
|
||||
}
|
||||
} else {
|
||||
output += snprintf(output,
|
||||
end - output,
|
||||
@@ -284,3 +321,222 @@ void end_meas(void) {
|
||||
msg->msgid = TIMESTAT_MSGID_END ;
|
||||
pushNotifiedFIFO(&measur_fifo, nfe);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief initializes sorted list
|
||||
* if dst is already initialized then asserts
|
||||
* \param time_stats_sorted_list sorted list to be initialized
|
||||
* \param size size of the sorted list
|
||||
*/
|
||||
void init_time_stats_sorted_list(time_stats_sorted_list_t *time_stats_sorted_list, unsigned int size)
|
||||
{
|
||||
if (time_stats_sorted_list->size == 0) {
|
||||
time_stats_sorted_list->list = calloc(size, sizeof(oai_cputime_t));
|
||||
time_stats_sorted_list->size = size;
|
||||
time_stats_sorted_list->nb_elm = 0;
|
||||
} else {
|
||||
AssertFatal(time_stats_sorted_list->size == 0, "Calling init_time_stats_sorted_list on initialized sorted list\n");
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \brief free sorted list
|
||||
* if dst is already free then does nothing
|
||||
* \param time_stats_sorted_list sorted list to be freed
|
||||
*/
|
||||
void free_time_stats_sorted_list(time_stats_sorted_list_t *time_stats_sorted_list)
|
||||
{
|
||||
if (time_stats_sorted_list->size > 0) {
|
||||
free(time_stats_sorted_list->list);
|
||||
time_stats_sorted_list->size = 0;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \brief returns true if the sorted list is enabled and false otherwise
|
||||
* \param time_stats_sorted_list sorted list to be tested
|
||||
*/
|
||||
int is_enabled_time_stats_sorted_list(const time_stats_sorted_list_t *time_stats_sorted_list)
|
||||
{
|
||||
return (time_stats_sorted_list->size > 0);
|
||||
}
|
||||
/**
|
||||
* \brief empties sorted list
|
||||
* if dst is not initialized then does nothing
|
||||
* \param time_stats_sorted_list sorted list to be emptied
|
||||
*/
|
||||
void reset_time_stats_sorted_list(time_stats_sorted_list_t *time_stats_sorted_list)
|
||||
{
|
||||
if (time_stats_sorted_list->size > 0) {
|
||||
time_stats_sorted_list->nb_elm = 0;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \brief inserts value sorted list
|
||||
* if dst is not initialized then does nothing
|
||||
* if dst is full then does nothing
|
||||
* \param time_stats_sorted_list sorted list to insert in
|
||||
* \param time time value to insert
|
||||
*/
|
||||
void insert_in_time_stats_sorted_list(time_stats_sorted_list_t *time_stats_sorted_list, oai_cputime_t time)
|
||||
{
|
||||
if (time_stats_sorted_list->size > 0) {
|
||||
if (time_stats_sorted_list->nb_elm < time_stats_sorted_list->size) {
|
||||
unsigned int i = 0;
|
||||
#ifdef DICHOTOMY
|
||||
unsigned int low = 0;
|
||||
unsigned int high = time_stats_sorted_list->nb_elm;
|
||||
bool converged = false;
|
||||
while (!converged) {
|
||||
i = (high + low) / 2;
|
||||
if (i > 0 && time_stats_sorted_list->list[i - 1] > time) {
|
||||
high = i - 1;
|
||||
} else if (i < time_stats_sorted_list->nb_elm && time_stats_sorted_list->list[i] < time) {
|
||||
low = i + 1;
|
||||
} else {
|
||||
converged = true;
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (; i < time_stats_sorted_list->nb_elm && time_stats_sorted_list->list[i] < time; i++);
|
||||
#endif
|
||||
// dst and src may overlap => use memmove rather than memcpy
|
||||
memmove(&time_stats_sorted_list->list[i+1], &time_stats_sorted_list->list[i], (time_stats_sorted_list->nb_elm - i) * sizeof(oai_cputime_t));
|
||||
time_stats_sorted_list->list[i] = time;
|
||||
time_stats_sorted_list->nb_elm++;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \brief copy sorted list src into dst, freeing and replacing dst
|
||||
* dst and src should be initialized, otherwise does nothing
|
||||
* \param dst destination sorted list
|
||||
* should be intitialized even with a dummy size 1 buffer to make sure that copying the list there is expected by the caller
|
||||
* \param src source sorted list
|
||||
*/
|
||||
void copy_time_stats_sorted_list(time_stats_sorted_list_t *dst, const time_stats_sorted_list_t *src)
|
||||
{
|
||||
if (dst->size > 0 && src->size > 0) {
|
||||
if (dst->size != src->size) {
|
||||
free_time_stats_sorted_list(dst);
|
||||
init_time_stats_sorted_list(dst, src->size);
|
||||
}
|
||||
memcpy(dst->list, src->list, src->nb_elm * sizeof(oai_cputime_t));
|
||||
dst->nb_elm = src->nb_elm;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \brief inserts the content of sorted list src into dst
|
||||
* dst and src should be initialized, otherwise does nothing
|
||||
* if dst is not large enough to copy src then does nothing
|
||||
* \param dst destination sorted list
|
||||
* \param src source sorted list
|
||||
*/
|
||||
void merge_time_stats_sorted_list(time_stats_sorted_list_t *dst, const time_stats_sorted_list_t *src)
|
||||
{
|
||||
if (dst->size > 0 && src->size > 0) {
|
||||
if ((dst->size - dst->nb_elm) >= src->nb_elm) {
|
||||
unsigned int j = 0;
|
||||
for (unsigned int i = 0; i < src->nb_elm; i++) {
|
||||
#ifdef DICHOTOMY
|
||||
unsigned int low = j + 1;
|
||||
unsigned int high = dst->nb_elm;
|
||||
bool converged = false;
|
||||
while (!converged) {
|
||||
j = (high + low) / 2;
|
||||
if (j > 0 && dst->list[j - 1] > src->list[i]) {
|
||||
high = j - 1;
|
||||
} else if (j < dst->nb_elm && dst->list[j] < src->list[i]) {
|
||||
low = j + 1;
|
||||
} else {
|
||||
converged = true;
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (; j < dst->nb_elm && dst->list[j] < src->list[i]; j++);
|
||||
#endif
|
||||
// dst and src may overlap => use memmove rather than memcpy
|
||||
memmove(&dst->list[j+1], &dst->list[j], (dst->nb_elm - j) * sizeof(oai_cputime_t));
|
||||
dst->list[j] = src->list[i];
|
||||
dst->nb_elm++;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \brief get the minimum from a sorted list
|
||||
* if the sorted list is not initialized or empty then returns -1
|
||||
* \param time_stats_sorted_list sorted list to query
|
||||
*/
|
||||
oai_cputime_t get_min(time_stats_sorted_list_t *time_stats_sorted_list)
|
||||
{
|
||||
if (time_stats_sorted_list->size > 0 && time_stats_sorted_list->nb_elm > 0) {
|
||||
return time_stats_sorted_list->list[0];
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \brief get the median from a sorted list
|
||||
* if the sorted list is not initialized or empty then returns -1
|
||||
* \param time_stats_sorted_list sorted list to query
|
||||
*/
|
||||
oai_cputime_t get_median(time_stats_sorted_list_t *time_stats_sorted_list)
|
||||
{
|
||||
if (time_stats_sorted_list->size > 0 && time_stats_sorted_list->nb_elm > 0) {
|
||||
return time_stats_sorted_list->list[time_stats_sorted_list->nb_elm / 2];
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \brief get the first quartile from a sorted list
|
||||
* if the sorted list is not initialized or empty then returns -1
|
||||
* \param time_stats_sorted_list sorted list to query
|
||||
*/
|
||||
oai_cputime_t get_q1(time_stats_sorted_list_t *time_stats_sorted_list)
|
||||
{
|
||||
if (time_stats_sorted_list->size > 0 && time_stats_sorted_list->nb_elm > 0) {
|
||||
return time_stats_sorted_list->list[time_stats_sorted_list->nb_elm / 4];
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \brief get the third quartile from a sorted list
|
||||
* if the sorted list is not initialized or empty then returns -1
|
||||
* \param time_stats_sorted_list sorted list to query
|
||||
*/
|
||||
oai_cputime_t get_q3(time_stats_sorted_list_t *time_stats_sorted_list)
|
||||
{
|
||||
if (time_stats_sorted_list->size > 0 && time_stats_sorted_list->nb_elm > 0) {
|
||||
return time_stats_sorted_list->list[3 * time_stats_sorted_list->nb_elm / 4];
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \brief get the first decile from a sorted list
|
||||
* if the sorted list is not initialized or empty then returns -1
|
||||
* \param time_stats_sorted_list sorted list to query
|
||||
*/
|
||||
oai_cputime_t get_d1(time_stats_sorted_list_t *time_stats_sorted_list)
|
||||
{
|
||||
if (time_stats_sorted_list->size > 0 && time_stats_sorted_list->nb_elm > 0) {
|
||||
return time_stats_sorted_list->list[time_stats_sorted_list->nb_elm / 10];
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \brief get the nineth decile from a sorted list
|
||||
* if the sorted list is not initialized or empty then returns -1
|
||||
* \param time_stats_sorted_list sorted list to query
|
||||
*/
|
||||
oai_cputime_t get_d9(time_stats_sorted_list_t *time_stats_sorted_list)
|
||||
{
|
||||
if (time_stats_sorted_list->size > 0 && time_stats_sorted_list->nb_elm > 0) {
|
||||
return time_stats_sorted_list->list[9 * time_stats_sorted_list->nb_elm / 10];
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,20 +38,121 @@ typedef struct {
|
||||
meas_printfunc_t displayFunc; /*!< \brief function to call when DISPLAY message is received*/
|
||||
} time_stats_msg_t;
|
||||
|
||||
/**
|
||||
* \typedef time_stats_sorted_list_t
|
||||
* \brief sorted list of time stats to get med, q1, q2
|
||||
* it can be left disabled by leaving size equal to 0
|
||||
* \var size allocated size of the list
|
||||
* 0 is the sorted list is disabled
|
||||
* \var nb_elm number of elements in the list
|
||||
* \var list pointer to the list
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int size;
|
||||
unsigned int nb_elm;
|
||||
oai_cputime_t *list;
|
||||
} time_stats_sorted_list_t;
|
||||
|
||||
/**
|
||||
* \brief initializes sorted list
|
||||
* if dst is already initialized then asserts
|
||||
* \param time_stats_sorted_list sorted list to be initialized
|
||||
* \param size size of the sorted list
|
||||
*/
|
||||
void init_time_stats_sorted_list(time_stats_sorted_list_t *time_stats_sorted_list, unsigned int size);
|
||||
/**
|
||||
* \brief free sorted list
|
||||
* if dst is already free then does nothing
|
||||
* \param time_stats_sorted_list sorted list to be freed
|
||||
*/
|
||||
void free_time_stats_sorted_list(time_stats_sorted_list_t *time_stats_sorted_list);
|
||||
/**
|
||||
* \brief returns true if the sorted list is enabled and false otherwise
|
||||
* \param time_stats_sorted_list sorted list to be tested
|
||||
*/
|
||||
int is_enabled_time_stats_sorted_list(const time_stats_sorted_list_t *time_stats_sorted_list);
|
||||
/**
|
||||
* \brief empties sorted list
|
||||
* if dst is not initialized then does nothing
|
||||
* \param time_stats_sorted_list sorted list to be emptied
|
||||
*/
|
||||
void reset_time_stats_sorted_list(time_stats_sorted_list_t *time_stats_sorted_list);
|
||||
/**
|
||||
* \brief inserts value sorted list
|
||||
* if dst is not initialized then does nothing
|
||||
* if dst is full then does nothing
|
||||
* \param time_stats_sorted_list sorted list to insert in
|
||||
* \param time time value to insert
|
||||
*/
|
||||
void insert_in_time_stats_sorted_list(time_stats_sorted_list_t *time_stats_sorted_list, oai_cputime_t time);
|
||||
/**
|
||||
* \brief copy sorted list src into dst, freeing and replacing dst
|
||||
* dst and src should be initialized, otherwise does nothing
|
||||
* \param dst destination sorted list
|
||||
* should be intitialized even with a dummy size 1 buffer to make sure that copying the list there is expected by the caller
|
||||
* \param src source sorted list
|
||||
*/
|
||||
void copy_time_stats_sorted_list(time_stats_sorted_list_t *dst, const time_stats_sorted_list_t *src);
|
||||
/**
|
||||
* \brief inserts the content of sorted list src into dst
|
||||
* dst and src should be initialized, otherwise does nothing
|
||||
* if dst is not large enough to copy src then does nothing
|
||||
* \param dst destination sorted list
|
||||
* \param src source sorted list
|
||||
*/
|
||||
void merge_time_stats_sorted_list(time_stats_sorted_list_t *dst, const time_stats_sorted_list_t *src);
|
||||
/**
|
||||
* \brief get the minimum from a sorted list
|
||||
* if the sorted list is not initialized or empty then returns -1
|
||||
* \param time_stats_sorted_list sorted list to query
|
||||
*/
|
||||
oai_cputime_t get_min(time_stats_sorted_list_t *time_stats_sorted_list);
|
||||
/**
|
||||
* \brief get the median from a sorted list
|
||||
* if the sorted list is not initialized or empty then returns -1
|
||||
* \param time_stats_sorted_list sorted list to query
|
||||
*/
|
||||
oai_cputime_t get_median(time_stats_sorted_list_t *time_stats_sorted_list);
|
||||
/**
|
||||
* \brief get the first quartile from a sorted list
|
||||
* if the sorted list is not initialized or empty then returns -1
|
||||
* \param time_stats_sorted_list sorted list to query
|
||||
*/
|
||||
oai_cputime_t get_q1(time_stats_sorted_list_t *time_stats_sorted_list);
|
||||
/**
|
||||
* \brief get the third quartile from a sorted list
|
||||
* if the sorted list is not initialized or empty then returns -1
|
||||
* \param time_stats_sorted_list sorted list to query
|
||||
*/
|
||||
oai_cputime_t get_q3(time_stats_sorted_list_t *time_stats_sorted_list);
|
||||
/**
|
||||
* \brief get the first decile from a sorted list
|
||||
* if the sorted list is not initialized or empty then returns -1
|
||||
* \param time_stats_sorted_list sorted list to query
|
||||
*/
|
||||
oai_cputime_t get_d1(time_stats_sorted_list_t *time_stats_sorted_list);
|
||||
/**
|
||||
* \brief get the nineth decile from a sorted list
|
||||
* if the sorted list is not initialized or empty then returns -1
|
||||
* \param time_stats_sorted_list sorted list to query
|
||||
*/
|
||||
oai_cputime_t get_d9(time_stats_sorted_list_t *time_stats_sorted_list);
|
||||
|
||||
struct notifiedFIFO_elt_s;
|
||||
typedef struct time_stats {
|
||||
oai_cputime_t in; /*!< \brief time at measure starting point */
|
||||
oai_cputime_t diff; /*!< \brief average difference between time at starting point and time at endpoint*/
|
||||
oai_cputime_t p_time; /*!< \brief absolute process duration */
|
||||
double diff_square; /*!< \brief process duration square */
|
||||
oai_cputime_t max; /*!< \brief maximum difference between time at starting point and time at endpoint*/
|
||||
int trials; /*!< \brief number of start point - end point iterations */
|
||||
int meas_flag; /*!< \brief 1: stop_meas not called (consecutive calls of start_meas) */
|
||||
char *meas_name; /*!< \brief name to use when printing the measure (not used for PHY simulators)*/
|
||||
int meas_index; /*!< \brief index of this measure in the measure array (not used for PHY simulators)*/
|
||||
int meas_enabled; /*!< \brief per measure enablement flag. send_meas tests this flag, unused today in start_meas and stop_meas*/
|
||||
struct notifiedFIFO_elt_s *tpoolmsg; /*!< \brief message pushed to the cpu measurment queue to report a measure START or STOP */
|
||||
time_stats_msg_t *tstatptr; /*!< \brief pointer to the time_stats_msg_t data in the tpoolmsg, stored here for perf considerations*/
|
||||
oai_cputime_t in; /*!< \brief time at measure starting point */
|
||||
oai_cputime_t diff; /*!< \brief average difference between time at starting point and time at endpoint*/
|
||||
oai_cputime_t p_time; /*!< \brief absolute process duration */
|
||||
double diff_square; /*!< \brief process duration square */
|
||||
oai_cputime_t max; /*!< \brief maximum difference between time at starting point and time at endpoint*/
|
||||
int trials; /*!< \brief number of start point - end point iterations */
|
||||
int meas_flag; /*!< \brief 1: stop_meas not called (consecutive calls of start_meas) */
|
||||
char *meas_name; /*!< \brief name to use when printing the measure (not used for PHY simulators)*/
|
||||
int meas_index; /*!< \brief index of this measure in the measure array (not used for PHY simulators)*/
|
||||
int meas_enabled; /*!< \brief per measure enablement flag. send_meas tests this flag, unused today in start_meas and stop_meas*/
|
||||
struct notifiedFIFO_elt_s *tpoolmsg; /*!< \brief message pushed to the cpu measurment queue to report a measure START or STOP */
|
||||
time_stats_msg_t *tstatptr; /*!< \brief pointer to the time_stats_msg_t data in the tpoolmsg, stored here for perf considerations */
|
||||
time_stats_sorted_list_t time_stats_sorted_list; /*!< \brief optional sorted list to get med, q1, q2 */
|
||||
} time_stats_t;
|
||||
#define MEASURE_ENABLED(X) (X->meas_enabled)
|
||||
|
||||
@@ -60,6 +161,10 @@ static inline void stop_meas(time_stats_t *ts) __attribute__((always_inline));
|
||||
|
||||
void print_meas_now(time_stats_t *ts, const char *name, FILE *file_name);
|
||||
void print_meas(time_stats_t *ts, const char *name, time_stats_t *total_exec_time, time_stats_t *sf_exec_time);
|
||||
size_t print_meas_log_header(time_stats_t *total_exec_time,
|
||||
time_stats_t *sf_exec_time,
|
||||
char *output,
|
||||
size_t outputlen);
|
||||
size_t print_meas_log(time_stats_t *ts,
|
||||
const char *name,
|
||||
time_stats_t *total_exec_time,
|
||||
@@ -101,6 +206,19 @@ static inline uint32_t rdtsc_oai(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline long long clock_gettime_oai()
|
||||
{
|
||||
struct timespec time;
|
||||
#ifdef CLOCK_MONOTONIC_RAW
|
||||
// CLOCK_MONOTONIC_RAW only on linux
|
||||
// See clock_getres(2)
|
||||
clock_gettime(CLOCK_MONOTONIC_RAW, &time);
|
||||
#else
|
||||
clock_gettime(CLOCK_REALTIME, &time);
|
||||
#endif
|
||||
return 1e+9 * time.tv_sec + time.tv_nsec;
|
||||
}
|
||||
|
||||
#define CPUMEAS_DISABLE 0
|
||||
#define CPUMEAS_ENABLE 1
|
||||
#define CPUMEAS_GETSTATE 2
|
||||
@@ -126,10 +244,10 @@ static inline void start_meas(time_stats_t *ts) {
|
||||
if (cpu_meas_enabled) {
|
||||
if (ts->meas_flag==0) {
|
||||
ts->trials++;
|
||||
ts->in = rdtsc_oai();
|
||||
ts->in = clock_gettime_oai();
|
||||
ts->meas_flag=1;
|
||||
} else {
|
||||
ts->in = rdtsc_oai();
|
||||
ts->in = clock_gettime_oai();
|
||||
}
|
||||
if ((ts->trials&16383)<10) ts->max=0;
|
||||
}
|
||||
@@ -137,7 +255,7 @@ static inline void start_meas(time_stats_t *ts) {
|
||||
|
||||
static inline void stop_meas(time_stats_t *ts) {
|
||||
if (cpu_meas_enabled) {
|
||||
long long out = rdtsc_oai();
|
||||
long long out = clock_gettime_oai();
|
||||
if (ts->in) {
|
||||
ts->diff += (out - ts->in);
|
||||
/// process duration is the difference between two clock points
|
||||
@@ -147,6 +265,7 @@ static inline void stop_meas(time_stats_t *ts) {
|
||||
if ((out - ts->in) > ts->max)
|
||||
ts->max = out - ts->in;
|
||||
|
||||
insert_in_time_stats_sorted_list(&ts->time_stats_sorted_list, (out - ts->in));
|
||||
ts->meas_flag = 0;
|
||||
}
|
||||
}
|
||||
@@ -160,6 +279,7 @@ static inline void reset_meas(time_stats_t *ts) {
|
||||
ts->max=0;
|
||||
ts->trials=0;
|
||||
ts->meas_flag=0;
|
||||
reset_time_stats_sorted_list(&ts->time_stats_sorted_list);
|
||||
}
|
||||
|
||||
static inline void copy_meas(time_stats_t *dst_ts,time_stats_t *src_ts) {
|
||||
@@ -167,6 +287,7 @@ static inline void copy_meas(time_stats_t *dst_ts,time_stats_t *src_ts) {
|
||||
dst_ts->trials=src_ts->trials;
|
||||
dst_ts->diff=src_ts->diff;
|
||||
dst_ts->max=src_ts->max;
|
||||
copy_time_stats_sorted_list(&dst_ts->time_stats_sorted_list, &src_ts->time_stats_sorted_list);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,6 +300,23 @@ static inline void merge_meas(time_stats_t *dst_ts, const time_stats_t *src_ts)
|
||||
dst_ts->diff_square += src_ts->diff_square;
|
||||
if (src_ts->max > dst_ts->max)
|
||||
dst_ts->max = src_ts->max;
|
||||
if (is_enabled_time_stats_sorted_list(&src_ts->time_stats_sorted_list)) {
|
||||
merge_time_stats_sorted_list(&dst_ts->time_stats_sorted_list, &src_ts->time_stats_sorted_list);
|
||||
} else if (src_ts->trials == 1) {
|
||||
insert_in_time_stats_sorted_list(&dst_ts->time_stats_sorted_list, src_ts->max);
|
||||
}
|
||||
}
|
||||
|
||||
#define TIME_STATS_ADVANCED_MODE 2
|
||||
|
||||
static inline void init_sorted_list_meas(time_stats_t *ts, unsigned int size)
|
||||
{
|
||||
init_time_stats_sorted_list(&ts->time_stats_sorted_list, size);
|
||||
}
|
||||
|
||||
static inline void free_sorted_list_meas(time_stats_t *ts)
|
||||
{
|
||||
free_time_stats_sorted_list(&ts->time_stats_sorted_list);
|
||||
}
|
||||
|
||||
#define CPUMEASUR_SECTION "cpumeasur"
|
||||
|
||||
@@ -207,14 +207,23 @@ static void rx_func(processingData_L1_t *info)
|
||||
static size_t dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output, size_t outputlen) {
|
||||
const char *begin = output;
|
||||
const char *end = output + outputlen;
|
||||
output += print_meas_log_header(NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->l1_tx_proc, "L1 Tx job", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->l1_rx_proc, "L1 Rx job", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->phy_proc_tx, "L1 Tx processing", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->dlsch_encoding_stats, "DLSCH encoding", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->dlsch_segmentation_stats, "DL segment segmentation", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->tinput, "DL encoding input", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->tprep, "DL encoding preparation", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->tparity, "DL encoding parity", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->toutput, "DL encoding output", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->dlsch_rate_matching_stats, "DL rate matching", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->dlsch_interleaving_stats, "DL interleaving", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->dlsch_scrambling_stats, "DLSCH scrambling", NULL, NULL, output, end-output);
|
||||
output += print_meas_log(&gNB->dlsch_modulation_stats, "DLSCH modulation", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->dlsch_pdsch_generation_stats, "PDSCH generation", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->phy_proc_rx, "L1 Rx processing", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->ulsch_decoding_stats, "ULSCH decoding", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->ts_deinterleave, "UL segment deinterleaving", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->ts_rate_unmatch, "UL segment rate recovery", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->ts_ldpc_decode, "UL segments decoding", NULL, NULL, output, end - output);
|
||||
@@ -222,8 +231,9 @@ static size_t dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output, size
|
||||
output += print_meas_log(&gNB->slot_indication_stats, "Slot Indication", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->rx_pusch_stats, "PUSCH inner-receiver", NULL, NULL, output, end - output);
|
||||
output += print_meas_log(&gNB->rx_prach, "PRACH RX", NULL, NULL, output, end - output);
|
||||
if (ru->feprx)
|
||||
if (ru->feprx) {
|
||||
output += print_meas_log(&ru->ofdm_demod_stats, "feprx", NULL, NULL, output, end - output);
|
||||
}
|
||||
|
||||
bool full_slot = ru->half_slot_parallelization == 0;
|
||||
if (ru->feptx_prec) {
|
||||
@@ -247,8 +257,9 @@ static size_t dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output, size
|
||||
output += print_meas_log(&ru->txdataF_copy_stats, "txdataF_copy", NULL, NULL, output, end - output);
|
||||
}
|
||||
|
||||
if (ru->fh_north_asynch_in)
|
||||
if (ru->fh_north_asynch_in) {
|
||||
output += print_meas_log(&ru->rx_fhaul,"rx_fhaul",NULL,NULL, output, end - output);
|
||||
}
|
||||
|
||||
output += print_meas_log(&ru->tx_fhaul,"tx_fhaul",NULL,NULL, output, end - output);
|
||||
|
||||
@@ -256,9 +267,26 @@ static size_t dump_L1_meas_stats(PHY_VARS_gNB *gNB, RU_t *ru, char *output, size
|
||||
output += print_meas_log(&ru->compression,"compression",NULL,NULL, output, end - output);
|
||||
output += print_meas_log(&ru->transport,"transport",NULL,NULL, output, end - output);
|
||||
}
|
||||
|
||||
if (cpu_meas_enabled == TIME_STATS_ADVANCED_MODE) {
|
||||
reset_meas(&gNB->l1_tx_proc);
|
||||
reset_meas(&gNB->l1_rx_proc);
|
||||
reset_meas(&gNB->phy_proc_tx);
|
||||
reset_meas(&gNB->dlsch_encoding_stats);
|
||||
reset_meas(&gNB->dlsch_pdsch_generation_stats);
|
||||
reset_meas(&gNB->phy_proc_rx);
|
||||
reset_meas(&gNB->ulsch_decoding_stats);
|
||||
reset_meas(&gNB->rx_pusch_stats);
|
||||
reset_meas(&gNB->rx_prach);
|
||||
if (ru->fh_north_asynch_in) {
|
||||
reset_meas(&ru->rx_fhaul);
|
||||
}
|
||||
reset_meas(&ru->tx_fhaul);
|
||||
}
|
||||
return output - begin;
|
||||
}
|
||||
|
||||
#define SORTED_LIST_SIZE 2048
|
||||
void *nrL1_stats_thread(void *param) {
|
||||
PHY_VARS_gNB *gNB = (PHY_VARS_gNB *)param;
|
||||
RU_t *ru = RC.ru[0];
|
||||
@@ -271,20 +299,66 @@ void *nrL1_stats_thread(void *param) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (cpu_meas_enabled == TIME_STATS_ADVANCED_MODE) {
|
||||
init_sorted_list_meas(&gNB->l1_tx_proc, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->l1_rx_proc, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->phy_proc_tx, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->dlsch_encoding_stats, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->dlsch_pdsch_generation_stats, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->phy_proc_rx, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->ulsch_decoding_stats, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->rx_pusch_stats, SORTED_LIST_SIZE);
|
||||
init_sorted_list_meas(&gNB->rx_prach, SORTED_LIST_SIZE);
|
||||
if (ru->fh_north_asynch_in) {
|
||||
init_sorted_list_meas(&ru->rx_fhaul, SORTED_LIST_SIZE);
|
||||
}
|
||||
init_sorted_list_meas(&ru->tx_fhaul, SORTED_LIST_SIZE);
|
||||
}
|
||||
|
||||
reset_meas(&gNB->l1_tx_proc);
|
||||
reset_meas(&gNB->l1_rx_proc);
|
||||
reset_meas(&gNB->phy_proc_tx);
|
||||
reset_meas(&gNB->dlsch_encoding_stats);
|
||||
reset_meas(&gNB->dlsch_segmentation_stats);
|
||||
reset_meas(&gNB->tinput);
|
||||
reset_meas(&gNB->tprep);
|
||||
reset_meas(&gNB->tparity);
|
||||
reset_meas(&gNB->toutput);
|
||||
reset_meas(&gNB->dlsch_rate_matching_stats);
|
||||
reset_meas(&gNB->dlsch_interleaving_stats);
|
||||
reset_meas(&gNB->dlsch_scrambling_stats);
|
||||
reset_meas(&gNB->dlsch_modulation_stats);
|
||||
reset_meas(&gNB->dlsch_pdsch_generation_stats);
|
||||
reset_meas(&gNB->phy_proc_rx);
|
||||
reset_meas(&gNB->ulsch_decoding_stats);
|
||||
reset_meas(&gNB->ts_deinterleave);
|
||||
reset_meas(&gNB->ts_rate_unmatch);
|
||||
reset_meas(&gNB->ts_ldpc_decode);
|
||||
reset_meas(&gNB->ul_indication_stats);
|
||||
reset_meas(&gNB->slot_indication_stats);
|
||||
reset_meas(&gNB->rx_pusch_stats);
|
||||
reset_meas(&gNB->dlsch_scrambling_stats);
|
||||
reset_meas(&gNB->dlsch_modulation_stats);
|
||||
reset_meas(&gNB->dlsch_pdsch_generation_stats);
|
||||
reset_meas(&gNB->rx_prach);
|
||||
|
||||
if (ru->feprx) {
|
||||
reset_meas(&ru->ofdm_demod_stats);
|
||||
}
|
||||
if (ru->feptx_prec) {
|
||||
reset_meas(&ru->precoding_stats);
|
||||
}
|
||||
if (ru->feptx_ofdm) {
|
||||
reset_meas(&ru->txdataF_copy_stats);
|
||||
reset_meas(&ru->ofdm_mod_stats);
|
||||
reset_meas(&ru->ofdm_total_stats);
|
||||
}
|
||||
if (ru->fh_north_asynch_in) {
|
||||
reset_meas(&ru->rx_fhaul);
|
||||
}
|
||||
reset_meas(&ru->tx_fhaul);
|
||||
if (ru->fh_north_out) {
|
||||
reset_meas(&ru->compression);
|
||||
reset_meas(&ru->transport);
|
||||
}
|
||||
|
||||
while (!oai_exit) {
|
||||
sleep(1);
|
||||
if (ftruncate(fileno(fd), 0) != 0 || fseek(fd, 0, SEEK_SET) != 0) {
|
||||
@@ -298,6 +372,23 @@ void *nrL1_stats_thread(void *param) {
|
||||
fprintf(fd,"%s\n",output);
|
||||
fflush(fd);
|
||||
}
|
||||
|
||||
if (cpu_meas_enabled == TIME_STATS_ADVANCED_MODE) {
|
||||
free_sorted_list_meas(&gNB->l1_tx_proc);
|
||||
free_sorted_list_meas(&gNB->l1_rx_proc);
|
||||
free_sorted_list_meas(&gNB->phy_proc_tx);
|
||||
free_sorted_list_meas(&gNB->dlsch_encoding_stats);
|
||||
free_sorted_list_meas(&gNB->dlsch_pdsch_generation_stats);
|
||||
free_sorted_list_meas(&gNB->phy_proc_rx);
|
||||
free_sorted_list_meas(&gNB->ulsch_decoding_stats);
|
||||
free_sorted_list_meas(&gNB->rx_pusch_stats);
|
||||
free_sorted_list_meas(&gNB->rx_prach);
|
||||
if (ru->fh_north_asynch_in) {
|
||||
free_sorted_list_meas(&ru->rx_fhaul);
|
||||
}
|
||||
free_sorted_list_meas(&ru->tx_fhaul);
|
||||
}
|
||||
|
||||
fclose(fd);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
/* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */
|
||||
#define CONFIG_HLP_DLMCS_PHYTEST "Set the downlink MCS for PHYTEST mode\n"
|
||||
#define CONFIG_HLP_DLNL_PHYTEST "Set the downlink nrOfLayers for PHYTEST mode\n"
|
||||
#define CONFIG_HLP_DLPMI_PHYTEST "Set the downlink Precoding Matrix Index for PHYTEST mode\n"
|
||||
#define CONFIG_HLP_ULNL_PHYTEST "Set the uplink nrOfLayers for PHYTEST mode\n"
|
||||
#define CONFIG_HLP_DLBW_PHYTEST "Set the number of PRBs used for DLSCH in PHYTEST mode\n"
|
||||
#define CONFIG_HLP_ULBW_PHYTEST "Set the number of PRBs used for ULSCH in PHYTEST mode\n"
|
||||
|
||||
@@ -21,9 +21,10 @@
|
||||
/*----------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
// clang-format off
|
||||
#define CMDLINE_PARAMS_DESC_GNB { \
|
||||
{"m" , CONFIG_HLP_DLMCS_PHYTEST, 0, .uptr=&target_dl_mcs, .defintval=0, TYPE_UINT, 0}, \
|
||||
{"l" , CONFIG_HLP_DLNL_PHYTEST, 0, .uptr=&target_dl_Nl, .defintval=0, TYPE_UINT, 0}, \
|
||||
{"L" , CONFIG_HLP_ULNL_PHYTEST, 0, .uptr=&target_ul_Nl, .defintval=0, TYPE_UINT, 0}, \
|
||||
{"p" , CONFIG_HLP_DLPMI_PHYTEST, 0, .uptr=&target_dl_pmi, .defintval=0, TYPE_UINT, 0}, \
|
||||
{"m" , CONFIG_HLP_DLMCS_PHYTEST, 0, .uptr=&target_dl_mcs, .defintval=0, TYPE_UINT, 0}, \
|
||||
{"t" , CONFIG_HLP_ULMCS_PHYTEST, 0, .uptr=&target_ul_mcs, .defintval=0, TYPE_UINT, 0}, \
|
||||
{"M" , CONFIG_HLP_DLBW_PHYTEST, 0, .uptr=&target_dl_bw, .defintval=0, TYPE_UINT, 0}, \
|
||||
{"T" , CONFIG_HLP_ULBW_PHYTEST, 0, .uptr=&target_ul_bw, .defintval=0, TYPE_UINT, 0}, \
|
||||
@@ -36,9 +37,10 @@
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
extern uint32_t target_dl_mcs;
|
||||
extern uint32_t target_dl_Nl;
|
||||
extern uint32_t target_ul_Nl;
|
||||
extern uint32_t target_dl_pmi;
|
||||
extern uint32_t target_dl_mcs;
|
||||
extern uint32_t target_ul_mcs;
|
||||
extern uint32_t target_dl_bw;
|
||||
extern uint32_t target_ul_bw;
|
||||
|
||||
@@ -118,7 +118,7 @@ extern int usrp_tx_thread;
|
||||
{"CO" , CONFIG_HLP_ULF, 0, .i64ptr=&(uplink_frequency_offset[0][0]), .defintval=0, TYPE_INT64, 0}, \
|
||||
{"a" , CONFIG_HLP_CHOFF, 0, .iptr=&CHAIN_OFFSET, .defintval=0, TYPE_INT, 0}, \
|
||||
{"d" , CONFIG_HLP_SOFTS, PARAMFLAG_BOOL, .uptr=&do_forms, .defintval=0, TYPE_UINT, 0}, \
|
||||
{"q" , CONFIG_HLP_STMON, PARAMFLAG_BOOL, .iptr=&cpu_meas_enabled, .defintval=0, TYPE_INT, 0}, \
|
||||
{"q" , CONFIG_HLP_STMON, PARAMFLAG_VALUE_OPTIONAL, .iptr=&cpu_meas_enabled, .defintval=0, TYPE_INT, 0}, \
|
||||
{"numerology" , CONFIG_HLP_NUMEROLOGY, 0, .iptr=&NUMEROLOGY, .defintval=1, TYPE_INT, 0}, \
|
||||
{"band" , CONFIG_HLP_BAND, 0, .iptr=&BAND, .defintval=78, TYPE_INT, 0}, \
|
||||
{"parallel-config", CONFIG_HLP_PARALLEL_CMD, 0, .strptr=¶llel_config, .defstrval=NULL, TYPE_STRING, 0}, \
|
||||
|
||||
@@ -125,7 +125,8 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
// Initiate timing. (Results depend on CPU Frequency. Therefore, might change due to performance variances during simulation.)
|
||||
time_stats_t timeEncoder, timeDecoder;
|
||||
time_stats_t timeEncoder = {0};
|
||||
time_stats_t timeDecoder = {0};
|
||||
cpu_meas_enabled = 1;
|
||||
reset_meas(&timeEncoder);
|
||||
reset_meas(&timeDecoder);
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
configmodule_interface_t *uniqCfg = NULL;
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
time_stats_t timeEncoder, timeDecoder;
|
||||
time_stats_t timeEncoder = {0};
|
||||
time_stats_t timeDecoder = {0};
|
||||
cpu_meas_enabled = 1;
|
||||
reset_meas(&timeEncoder);
|
||||
reset_meas(&timeDecoder);
|
||||
|
||||
@@ -899,10 +899,8 @@ static int pmd_lcore_ldpc_enc(void *arg)
|
||||
AssertFatal(ret == 0, "Allocation failed for %d ops", num_segments);
|
||||
set_ldpc_enc_op(ops_enq, bufs->inputs, bufs->hard_outputs, nrLDPC_slot_encoding_parameters);
|
||||
|
||||
if (nrLDPC_slot_encoding_parameters->tprep != NULL)
|
||||
stop_meas(nrLDPC_slot_encoding_parameters->tprep);
|
||||
if (nrLDPC_slot_encoding_parameters->tparity != NULL)
|
||||
start_meas(nrLDPC_slot_encoding_parameters->tparity);
|
||||
stop_meas(&nrLDPC_slot_encoding_parameters->TBs[0].segments[0].tprep);
|
||||
start_meas(&nrLDPC_slot_encoding_parameters->TBs[0].segments[0].tparity);
|
||||
|
||||
uint16_t enq = 0, deq = 0;
|
||||
while (enq < num_segments) {
|
||||
@@ -916,14 +914,11 @@ static int pmd_lcore_ldpc_enc(void *arg)
|
||||
time_out++;
|
||||
DevAssert(time_out <= TIME_OUT_POLL);
|
||||
}
|
||||
if (nrLDPC_slot_encoding_parameters->tparity != NULL)
|
||||
stop_meas(nrLDPC_slot_encoding_parameters->tparity);
|
||||
if (nrLDPC_slot_encoding_parameters->toutput != NULL)
|
||||
start_meas(nrLDPC_slot_encoding_parameters->toutput);
|
||||
stop_meas(&nrLDPC_slot_encoding_parameters->TBs[0].segments[0].tparity);
|
||||
start_meas(&nrLDPC_slot_encoding_parameters->TBs[0].segments[0].toutput);
|
||||
ret = retrieve_ldpc_enc_op(ops_deq, nrLDPC_slot_encoding_parameters);
|
||||
AssertFatal(ret == 0, "Failed to retrieve LDPC encoding op!");
|
||||
if (nrLDPC_slot_encoding_parameters->toutput != NULL)
|
||||
stop_meas(nrLDPC_slot_encoding_parameters->toutput);
|
||||
stop_meas(&nrLDPC_slot_encoding_parameters->TBs[0].segments[0].toutput);
|
||||
rte_bbdev_enc_op_free_bulk(ops_enq, num_segments);
|
||||
return ret;
|
||||
}
|
||||
@@ -1338,8 +1333,7 @@ int32_t nrLDPC_coding_decoder(nrLDPC_slot_decoding_parameters_t *nrLDPC_slot_dec
|
||||
int32_t nrLDPC_coding_encoder(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encoding_parameters)
|
||||
{
|
||||
pthread_mutex_lock(&encode_mutex);
|
||||
if (nrLDPC_slot_encoding_parameters->tprep != NULL)
|
||||
start_meas(nrLDPC_slot_encoding_parameters->tprep);
|
||||
start_meas(&nrLDPC_slot_encoding_parameters->TBs[0].segments[0].tprep);
|
||||
|
||||
const uint16_t num_segments = nb_segments_encoding(nrLDPC_slot_encoding_parameters);
|
||||
|
||||
|
||||
@@ -137,6 +137,10 @@ typedef struct nrLDPC_segment_encoding_parameters_s{
|
||||
time_stats_t ts_interleave;
|
||||
time_stats_t ts_rate_match;
|
||||
time_stats_t ts_ldpc_encode;
|
||||
time_stats_t tinput;
|
||||
time_stats_t tprep;
|
||||
time_stats_t tparity;
|
||||
time_stats_t toutput;
|
||||
} nrLDPC_segment_encoding_parameters_t;
|
||||
|
||||
/**
|
||||
@@ -210,10 +214,6 @@ typedef struct nrLDPC_slot_encoding_parameters_s{
|
||||
int slot;
|
||||
int nb_TBs;
|
||||
tpool_t *threadPool;
|
||||
time_stats_t *tinput;
|
||||
time_stats_t *tprep;
|
||||
time_stats_t *tparity;
|
||||
time_stats_t *toutput;
|
||||
nrLDPC_TB_encoding_parameters_t *TBs;
|
||||
} nrLDPC_slot_encoding_parameters_t;
|
||||
|
||||
|
||||
@@ -342,10 +342,6 @@ static int nrLDPC_launch_TB_encoding(nrLDPC_slot_encoding_parameters_t *nrLDPC_s
|
||||
|
||||
encoder_implemparams_t common_segment_params = {
|
||||
.n_segments = nrLDPC_TB_encoding_parameters->C,
|
||||
.tinput = nrLDPC_slot_encoding_parameters->tinput,
|
||||
.tprep = nrLDPC_slot_encoding_parameters->tprep,
|
||||
.tparity = nrLDPC_slot_encoding_parameters->tparity,
|
||||
.toutput = nrLDPC_slot_encoding_parameters->toutput,
|
||||
.Kb = nrLDPC_TB_encoding_parameters->Kb,
|
||||
.Zc = nrLDPC_TB_encoding_parameters->Z,
|
||||
.BG = nrLDPC_TB_encoding_parameters->BG,
|
||||
@@ -434,8 +430,6 @@ int nrLDPC_coding_encoder(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encodin
|
||||
uint32_t C = nrLDPC_TB_encoding_parameters->C;
|
||||
size_t n_seg = (C / 8 + ((C & 7) == 0 ? 0 : 1));
|
||||
|
||||
time_stats_t *toutput = nrLDPC_slot_encoding_parameters->toutput;
|
||||
|
||||
for (int j = 0; j < n_seg; j++) {
|
||||
unsigned int macro_segment = j * 8;
|
||||
unsigned int macro_segment_end = (C > macro_segment + 8) ? macro_segment + 8 : C;
|
||||
@@ -454,7 +448,8 @@ int nrLDPC_coding_encoder(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encodin
|
||||
}
|
||||
}
|
||||
|
||||
if(toutput != NULL) start_meas(toutput);
|
||||
time_stats_t *toutput = &nrLDPC_TB_encoding_parameters->segments[macro_segment].toutput;
|
||||
start_meas(toutput);
|
||||
|
||||
uint32_t Eoffset=0;
|
||||
for (int s=0; s<macro_segment; s++)
|
||||
@@ -470,7 +465,7 @@ int nrLDPC_coding_encoder(nrLDPC_slot_encoding_parameters_t *nrLDPC_slot_encodin
|
||||
nrLDPC_TB_encoding_parameters->output,
|
||||
Eoffset);
|
||||
|
||||
if(toutput != NULL) stop_meas(toutput);
|
||||
stop_meas(toutput);
|
||||
}
|
||||
nbTasks += n_seg;
|
||||
}
|
||||
|
||||
@@ -713,7 +713,9 @@ static int do_one_dlsch(unsigned char *input_ptr, PHY_VARS_gNB *gNB, NR_gNB_DLSC
|
||||
re_beginning_of_symbol -= n_dmrs;
|
||||
}
|
||||
}
|
||||
memset(&rdata->dlsch_resource_mapping_stats, 0, sizeof(rdata->dlsch_resource_mapping_stats));
|
||||
reset_meas(&rdata->dlsch_resource_mapping_stats);
|
||||
memset(&rdata->dlsch_precoding_stats, 0, sizeof(rdata->dlsch_precoding_stats));
|
||||
reset_meas(&rdata->dlsch_precoding_stats);
|
||||
for (int l = 0; l < rel15->nrOfLayers; l++)
|
||||
rdata->tx_layers[l] = tx_layers[l];
|
||||
|
||||
@@ -238,6 +238,10 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
reset_meas(&segment_parameters->ts_interleave);
|
||||
reset_meas(&segment_parameters->ts_rate_match);
|
||||
reset_meas(&segment_parameters->ts_ldpc_encode);
|
||||
reset_meas(&segment_parameters->tinput);
|
||||
reset_meas(&segment_parameters->tprep);
|
||||
reset_meas(&segment_parameters->tparity);
|
||||
reset_meas(&segment_parameters->toutput);
|
||||
}
|
||||
|
||||
segments_offset += TB_parameters->C;
|
||||
@@ -253,10 +257,6 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
.slot = slot,
|
||||
.nb_TBs = n_dlsch,
|
||||
.threadPool = &gNB->threadPool,
|
||||
.tinput = tinput,
|
||||
.tprep = tprep,
|
||||
.tparity = tparity,
|
||||
.toutput = toutput,
|
||||
.TBs = TBs};
|
||||
gNB->nrLDPC_coding_interface.nrLDPC_coding_encoder(&slot_parameters);
|
||||
|
||||
@@ -267,6 +267,10 @@ int nr_dlsch_encoding(PHY_VARS_gNB *gNB,
|
||||
merge_meas(dlsch_interleaving_stats, &segment_parameters->ts_interleave);
|
||||
merge_meas(dlsch_rate_matching_stats, &segment_parameters->ts_rate_match);
|
||||
// merge_meas(, &segment_parameters->ts_ldpc_encode);
|
||||
merge_meas(tinput, &segment_parameters->tinput);
|
||||
merge_meas(tprep, &segment_parameters->tprep);
|
||||
merge_meas(tparity, &segment_parameters->tparity);
|
||||
merge_meas(toutput, &segment_parameters->toutput);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -269,7 +269,9 @@ int nr_ulsch_decoding(PHY_VARS_gNB *phy_vars_gNB,
|
||||
}
|
||||
}
|
||||
|
||||
start_meas(&phy_vars_gNB->ulsch_decoding_stats);
|
||||
int ret_decoder = phy_vars_gNB->nrLDPC_coding_interface.nrLDPC_coding_decoder(&slot_parameters);
|
||||
stop_meas(&phy_vars_gNB->ulsch_decoding_stats);
|
||||
|
||||
// post decode
|
||||
for (uint8_t pusch_id = 0; pusch_id < nb_pusch; pusch_id++) {
|
||||
|
||||
@@ -151,10 +151,6 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
|
||||
.slot = slot,
|
||||
.nb_TBs = nb_ulsch,
|
||||
.threadPool = &get_nrUE_params()->Tpool,
|
||||
.tinput = NULL,
|
||||
.tprep = NULL,
|
||||
.tparity = NULL,
|
||||
.toutput = NULL,
|
||||
.TBs = TBs};
|
||||
|
||||
int max_num_segments = 0;
|
||||
@@ -208,6 +204,10 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
|
||||
reset_meas(&segment_parameters->ts_interleave);
|
||||
reset_meas(&segment_parameters->ts_rate_match);
|
||||
reset_meas(&segment_parameters->ts_ldpc_encode);
|
||||
reset_meas(&segment_parameters->tinput);
|
||||
reset_meas(&segment_parameters->tprep);
|
||||
reset_meas(&segment_parameters->tparity);
|
||||
reset_meas(&segment_parameters->toutput);
|
||||
|
||||
} // TB_parameters->C
|
||||
} // pusch_id
|
||||
@@ -222,6 +222,10 @@ int nr_ulsch_encoding(PHY_VARS_NR_UE *ue,
|
||||
merge_meas(&ue->phy_cpu_stats.cpu_time_stats[ULSCH_INTERLEAVING_STATS], &segment_parameters->ts_interleave);
|
||||
merge_meas(&ue->phy_cpu_stats.cpu_time_stats[ULSCH_RATE_MATCHING_STATS], &segment_parameters->ts_rate_match);
|
||||
merge_meas(&ue->phy_cpu_stats.cpu_time_stats[ULSCH_LDPC_ENCODING_STATS], &segment_parameters->ts_ldpc_encode);
|
||||
merge_meas(&ue->phy_cpu_stats.cpu_time_stats[ULSCH_LDPC_INPUT_STATS], &segment_parameters->tinput);
|
||||
merge_meas(&ue->phy_cpu_stats.cpu_time_stats[ULSCH_LDPC_PREP_STATS], &segment_parameters->tprep);
|
||||
merge_meas(&ue->phy_cpu_stats.cpu_time_stats[ULSCH_LDPC_PARITY_STATS], &segment_parameters->tparity);
|
||||
merge_meas(&ue->phy_cpu_stats.cpu_time_stats[ULSCH_LDPC_OUTPUT_STATS], &segment_parameters->toutput);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ int cpu_meas_enabled;
|
||||
THREAD_STRUCT thread_struct;
|
||||
uint32_t target_ul_mcs = 9;
|
||||
uint32_t target_dl_mcs = 9;
|
||||
uint32_t target_dl_pmi = 0;
|
||||
uint64_t dlsch_slot_bitmap = (1<<1);
|
||||
uint64_t ulsch_slot_bitmap = (1<<8);
|
||||
uint32_t target_ul_bw = 50;
|
||||
|
||||
@@ -35,6 +35,10 @@
|
||||
FN(ULSCH_LDPC_ENCODING_STATS),\
|
||||
FN(ULSCH_RATE_MATCHING_STATS),\
|
||||
FN(ULSCH_INTERLEAVING_STATS),\
|
||||
FN(ULSCH_LDPC_INPUT_STATS),\
|
||||
FN(ULSCH_LDPC_PREP_STATS),\
|
||||
FN(ULSCH_LDPC_PARITY_STATS),\
|
||||
FN(ULSCH_LDPC_OUTPUT_STATS),\
|
||||
FN(ULSCH_ENCODING_STATS),\
|
||||
FN(OFDM_MOD_STATS),\
|
||||
FN(PRACH_GEN_STATS)
|
||||
|
||||
@@ -35,6 +35,7 @@ static bool is_xlsch_in_slot(uint64_t bitmap, uint32_t modval, slot_t slot)
|
||||
|
||||
uint32_t target_dl_mcs = 9;
|
||||
uint32_t target_dl_Nl = 1;
|
||||
uint32_t target_dl_pmi = 0;
|
||||
uint32_t target_dl_bw = 50;
|
||||
uint64_t dlsch_slot_bitmap = (1<<1);
|
||||
uint32_t dlsch_slot_modval = 0;
|
||||
@@ -158,7 +159,7 @@ void nr_preprocessor_phytest(gNB_MAC_INST *mac, post_process_pdsch_t *pp_pdsch)
|
||||
// tbSize further below
|
||||
.dl_harq_pid = sched_ctrl->retrans_dl_harq.head, // PID of HARQ awaiting retransmission, or -1 otherwise
|
||||
.pucch_allocation = alloc,
|
||||
.pm_index = 0,
|
||||
.pm_index = target_dl_pmi,
|
||||
.nrOfLayers = target_dl_Nl,
|
||||
.bwp_info = get_pdsch_bwp_start_size(mac, UE),
|
||||
.dmrs_parms = get_dl_dmrs_params(scc, dl_bwp, &tda_info, target_dl_Nl),
|
||||
|
||||
Reference in New Issue
Block a user