Commit 3b44919d authored by laurent's avatar laurent

better performance measurements

parent cedde4ad
......@@ -53,26 +53,6 @@
extern "C" {
#endif
extern double cpuf;
static inline unsigned long long rdtsc(void) {
unsigned long long a, d;
__asm__ volatile ("rdtsc" : "=a" (a), "=d" (d));
return (d<<32) | a;
}
static inline unsigned long long checkT(int timeout, char * file, int line) {
static unsigned long long __thread last=0;
unsigned long long cur=rdtsc();
int microCycles=(int)(cpuf*1000);
int duration=(int)((cur-last)/microCycles);
if ( last!=0 && duration > timeout )
printf("%s:%d lte-ue delay %d (exceed %d)\n", file, line,
duration, timeout);
last=cur;
return cur;
}
#define check(a) checkT(a,__FILE__,__LINE__)
/** @defgroup _LOG LOG Generator
* @{*/
/* @}*/
......@@ -96,41 +76,197 @@ extern "C" {
* @ingroup _macro
* @brief LOG defines 9 levels of messages for users. Importance of these levels decrease gradually from 0 to 8
* @{*/
#ifndef LOG_EMERG
# define LOG_EMERG 0 /*!< \brief system is unusable */
#endif
#ifndef LOG_ALERT
# define LOG_ALERT 1 /*!< \brief action must be taken immediately */
#endif
#ifndef LOG_CRIT
# define LOG_CRIT 2 /*!< \brief critical conditions */
#endif
#ifndef LOG_ERR
# define LOG_ERR 3 /*!< \brief error conditions */
#endif
#ifndef LOG_WARNING
# define LOG_WARNING 4 /*!< \brief warning conditions */
#endif
#ifndef LOG_NOTICE
# define LOG_NOTICE 5 /*!< \brief normal but significant condition */
#endif
#ifndef LOG_INFO
# define LOG_INFO 6 /*!< \brief informational */
#endif
#ifndef LOG_DEBUG
# define LOG_DEBUG 7 /*!< \brief debug-level messages */
#endif
#ifndef LOG_FILE
# define LOG_FILE 8 /*!< \brief message sequence chart -level */
#endif
#ifndef LOG_TRACE
# define LOG_TRACE 9 /*!< \brief trace-level messages */
#endif
#define NUM_LOG_LEVEL 10 /*!< \brief the number of message levels users have with LOG */
/* @}*/
/** @defgroup _log_format Defined log format
* @ingroup _macro
* @brief Macro of log formats defined by LOG
* @{*/
/* .log_format = 0x13 uncolored standard messages
* .log_format = 0x93 colored standard messages */
#define LOG_RED "\033[1;31m" /*!< \brief VT100 sequence for bold red foreground */
#define LOG_GREEN "\033[32m" /*!< \brief VT100 sequence for green foreground */
#define LOG_ORANGE "\033[93m" /*!< \brief VT100 sequence for orange foreground */
#define LOG_BLUE "\033[34m" /*!< \brief VT100 sequence for blue foreground */
#define LOG_CYBL "\033[40;36m" /*!< \brief VT100 sequence for cyan foreground on black background */
#define LOG_RESET "\033[0m" /*!< \brief VT100 sequence for reset (black) foreground */
/* @}*/
/** @defgroup _syslog_conf Macros for write in syslog.conf
* @ingroup _macro
* @brief Macros used to write lines (local/remote) in syslog.conf
* @{*/
#define LOG_LOCAL 0x01
#define LOG_REMOTE 0x02
#define FLAG_COLOR 0x001 /*!< \brief defaults */
#define FLAG_PID 0x002 /*!< \brief defaults */
#define FLAG_COMP 0x004
#define FLAG_THREAD 0x008 /*!< \brief all : 255/511 */
#define FLAG_LEVEL 0x010
#define FLAG_FUNCT 0x020
#define FLAG_FILE_LINE 0x040
#define FLAG_TIME 0x100
#define LOG_NONE 0x00
#define LOG_LOW 0x5
#define LOG_MED 0x15
#define LOG_HIGH 0x35
#define LOG_FULL 0x75
#define OAI_OK 0 /*!< \brief all ok */
#define OAI_ERR 1 /*!< \brief generic error */
#define OAI_ERR_READ_ONLY 2 /*!< \brief tried to write to read-only item */
#define OAI_ERR_NOTFOUND 3 /*!< \brief something wasn't found */
/* @}*/
//static char *log_level_highlight_start[] = {LOG_RED, LOG_RED, LOG_RED, LOG_RED, LOG_BLUE, "", "", "", LOG_GREEN}; /*!< \brief Optional start-format strings for highlighting */
//static char *log_level_highlight_end[] = {LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, "", "", "", LOG_RESET}; /*!< \brief Optional end-format strings for highlighting */
typedef enum {
MIN_LOG_COMPONENTS = 0,
PHY = MIN_LOG_COMPONENTS,
MAC,
EMU,
OCG,
OMG,
OPT,
OTG,
OTG_LATENCY,
OTG_LATENCY_BG,
OTG_GP,
OTG_GP_BG,
OTG_JITTER,
RLC,
PDCP,
RRC,
NAS,
PERF,
OIP,
CLI,
MSC,
OCM,
UDP_,
GTPU,
SPGW,
S1AP,
SCTP,
HW,
OSA,
RAL_ENB,
RAL_UE,
ENB_APP,
FLEXRAN_AGENT,
TMR,
USIM,
LOCALIZE,
RRH,
X2AP,
MAX_LOG_COMPONENTS,
}
comp_name_t;
//#define msg printf
typedef struct {
char *name; /*!< \brief string name of item */
int value; /*!< \brief integer value of mapping */
} mapping;
typedef struct {
const char *name;
int level;
int flag;
int interval;
int fd;
int filelog;
char *filelog_name;
/* SR: make the log buffer component relative */
char log_buffer[MAX_LOG_TOTAL];
} log_component_t;
typedef struct {
unsigned int remote_ip;
unsigned int audit_ip;
int remote_level;
int facility;
int audit_facility;
int format;
} log_config_t;
typedef struct {
log_component_t log_component[MAX_LOG_COMPONENTS];
log_config_t config;
char* level2string[NUM_LOG_LEVEL];
int level;
int onlinelog;
int flag;
int syslog;
int filelog;
char* filelog_name;
} log_t;
typedef struct LOG_params {
const char *file;
const char *func;
int line;
int comp;
int level;
const char *format;
char l_buff_info [MAX_LOG_INFO];
int len;
} LOG_params;
#if defined(ENABLE_ITTI)
typedef enum log_instance_type_e {
LOG_INSTANCE_UNKNOWN,
LOG_INSTANCE_ENB,
LOG_INSTANCE_UE,
} log_instance_type_t;
void log_set_instance_type (log_instance_type_t instance);
#endif
/*--- INCLUDES ---------------------------------------------------------------*/
# include "log_if.h"
/*----------------------------------------------------------------------------*/
int logInit (void);
void logRecord_mt(const char *file, const char *func, int line,int comp, int level, const char *format, ...);
void logRecord(const char *file, const char *func, int line,int comp, int level, const char *format, ...);
int set_comp_log(int component, int level, int verbosity, int interval);
int set_log(int component, int level, int interval);
void set_glog(int level, int verbosity);
void set_log_syslog(int enable);
void set_log_onlinelog(int enable);
void set_log_filelog(int enable);
void set_component_filelog(int comp);
int map_str_to_int(mapping *map, const char *str);
char *map_int_to_str(mapping *map, int val);
void logClean (void);
int is_newline( char *str, int size);
void *log_thread_function(void * list);
/** @defgroup _logIt logIt function
* @ingroup _macro
* @brief Macro used to call tr_log_full_ex with file, function and line information
......@@ -206,169 +342,82 @@ extern "C" {
#define LOG_RETURN(c,x) do {uint32_t __rv;__rv=(unsigned int)(x);LOG_T(c,"Returning %08x\n", __rv);return((typeof(x))__rv);}while(0) /*!< \brief Macro to log a function exit, including integer value, then to return a value to the calling function */
/* @}*/
/** @defgroup _log_format Defined log format
* @ingroup _macro
* @brief Macro of log formats defined by LOG
* @{*/
/* .log_format = 0x13 uncolored standard messages
* .log_format = 0x93 colored standard messages */
#define LOG_RED "\033[1;31m" /*!< \brief VT100 sequence for bold red foreground */
#define LOG_GREEN "\033[32m" /*!< \brief VT100 sequence for green foreground */
#define LOG_ORANGE "\033[93m" /*!< \brief VT100 sequence for orange foreground */
#define LOG_BLUE "\033[34m" /*!< \brief VT100 sequence for blue foreground */
#define LOG_CYBL "\033[40;36m" /*!< \brief VT100 sequence for cyan foreground on black background */
#define LOG_RESET "\033[0m" /*!< \brief VT100 sequence for reset (black) foreground */
/* @}*/
/** @defgroup _syslog_conf Macros for write in syslog.conf
* @ingroup _macro
* @brief Macros used to write lines (local/remote) in syslog.conf
* @{*/
#define LOG_LOCAL 0x01
#define LOG_REMOTE 0x02
#define FLAG_COLOR 0x001 /*!< \brief defaults */
#define FLAG_PID 0x002 /*!< \brief defaults */
#define FLAG_COMP 0x004
#define FLAG_THREAD 0x008 /*!< \brief all : 255/511 */
#define FLAG_LEVEL 0x010
#define FLAG_FUNCT 0x020
#define FLAG_FILE_LINE 0x040
#define FLAG_TIME 0x100
#define LOG_NONE 0x00
#define LOG_LOW 0x5
#define LOG_MED 0x15
#define LOG_HIGH 0x35
#define LOG_FULL 0x75
#define OAI_OK 0 /*!< \brief all ok */
#define OAI_ERR 1 /*!< \brief generic error */
#define OAI_ERR_READ_ONLY 2 /*!< \brief tried to write to read-only item */
#define OAI_ERR_NOTFOUND 3 /*!< \brief something wasn't found */
/* @}*/
//static char *log_level_highlight_start[] = {LOG_RED, LOG_RED, LOG_RED, LOG_RED, LOG_BLUE, "", "", "", LOG_GREEN}; /*!< \brief Optional start-format strings for highlighting */
//static char *log_level_highlight_end[] = {LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, "", "", "", LOG_RESET}; /*!< \brief Optional end-format strings for highlighting */
typedef enum {
MIN_LOG_COMPONENTS = 0,
PHY = MIN_LOG_COMPONENTS,
MAC,
EMU,
OCG,
OMG,
OPT,
OTG,
OTG_LATENCY,
OTG_LATENCY_BG,
OTG_GP,
OTG_GP_BG,
OTG_JITTER,
RLC,
PDCP,
RRC,
NAS,
PERF,
OIP,
CLI,
MSC,
OCM,
UDP_,
GTPU,
SPGW,
S1AP,
SCTP,
HW,
OSA,
RAL_ENB,
RAL_UE,
ENB_APP,
FLEXRAN_AGENT,
TMR,
USIM,
LOCALIZE,
RRH,
X2AP,
MAX_LOG_COMPONENTS,
static inline unsigned long long rdtsc(void) {
unsigned long long a, d;
__asm__ volatile ("rdtsc" : "=a" (a), "=d" (d));
return (d<<32) | a;
}
comp_name_t;
//#define msg printf
typedef struct {
char *name; /*!< \brief string name of item */
int value; /*!< \brief integer value of mapping */
} mapping;
typedef struct {
const char *name;
int level;
int flag;
int interval;
int fd;
int filelog;
char *filelog_name;
/* SR: make the log buffer component relative */
char log_buffer[MAX_LOG_TOTAL];
} log_component_t;
#define DEBUG_REALTIME 1
#if DEBUG_REALTIME
typedef struct {
unsigned int remote_ip;
unsigned int audit_ip;
int remote_level;
int facility;
int audit_facility;
int format;
} log_config_t;
extern double cpuf;
static inline unsigned long long checkT(int timeout, char * file, int line) {
static unsigned long long __thread last=0;
unsigned long long cur=rdtsc();
int microCycles=(int)(cpuf*1000);
int duration=(int)((cur-last)/microCycles);
if ( last!=0 && duration > timeout )
printf("%s:%d lte-ue delay %d (exceed %d)\n", file, line,
duration, timeout);
last=cur;
return cur;
}
typedef struct {
log_component_t log_component[MAX_LOG_COMPONENTS];
log_config_t config;
char* level2string[NUM_LOG_LEVEL];
int level;
int onlinelog;
int flag;
int syslog;
int filelog;
char* filelog_name;
} log_t;
typedef struct m {
unsigned long long iterations;
unsigned long long sum;
unsigned long long maxArray[11];
} Meas;
static inline void printMeas(char * txt, Meas *M, int period) {
if (M->iterations%period == 0 ) {
char txt2[512];
sprintf(txt2,"%s avg=%llu, iterations=%llu, max=%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu\n",
txt, M->sum/M->iterations,M->iterations,
M->maxArray[1],M->maxArray[2], M->maxArray[3],M->maxArray[4],
M->maxArray[5], M->maxArray[6],M->maxArray[7], M->maxArray[8],M->maxArray[9],M->maxArray[10]);
LOG_W(PHY,txt2);
}
}
typedef struct LOG_params {
const char *file;
const char *func;
int line;
int comp;
int level;
const char *format;
char l_buff_info [MAX_LOG_INFO];
int len;
} LOG_params;
static inline int cmpint(const void* a, const void* b) {
unsigned long long* aa=(unsigned long long*)a;
unsigned long long* bb=(unsigned long long*)b;
return (int)(*aa-*bb);
}
static inline void updateTimes(unsigned long long start, Meas *M, int period, char * txt) {
if (start!=0) {
unsigned long long end=rdtsc();
long long diff=(end-start)/(cpuf*1000);
M->maxArray[0]=diff;
M->sum+=diff;
M->iterations++;
qsort(M->maxArray, 11, sizeof(unsigned long long), cmpint);
printMeas(txt,M,period);
}
}
#if defined(ENABLE_ITTI)
typedef enum log_instance_type_e {
LOG_INSTANCE_UNKNOWN,
LOG_INSTANCE_ENB,
LOG_INSTANCE_UE,
} log_instance_type_t;
#define check(a) checkT(a,__FILE__,__LINE__)
#define initRefTimes(a) static __thread Meas a= {0}
#define pickTime(a) unsigned long long a=rdtsc()
#define readTime(a) a
#define initStaticTime(a) static __thread unsigned long long a={0}
#define pickStaticTime(a) a=rdtsc()
void log_set_instance_type (log_instance_type_t instance);
#else
#define check(a) do {} while (0)
#define initRefTimes(a) do {} while (0)
#define initStaticTime(a) do {} while (0)
#define pickTime(a) do {} while (0)
#define readTime(a) 0
#define pickStaticTime(a) do {} while (0)
#define updateTimes(a,b,c,d) do {} while (0)
#define printMeas(a,b,c) do {} while (0)
#endif
int logInit (void);
/*--- INCLUDES ---------------------------------------------------------------*/
# include "log_if.h"
/*----------------------------------------------------------------------------*/
#ifdef __cplusplus
}
#endif
......
......@@ -27,59 +27,8 @@
* \warning This component can be runned only in user-space
* @ingroup routing
*/
#ifndef __LOG_IF_H__
# define __LOG_IF_H__
/*--- INCLUDES ---------------------------------------------------------------*/
# include "log.h"
/*----------------------------------------------------------------------------*/
#ifdef __cplusplus
extern "C" {
#endif
# ifdef COMPONENT_LOG
# ifdef COMPONENT_LOG_IF
# define private_log_if(x) x
# define friend_log_if(x) x
# define public_log_if(x) x
# else
# define private_log_if(x)
# define friend_log_if(x) extern x
# define public_log_if(x) extern x
# endif
# else
# define private_log_if(x)
# define friend_log_if(x)
# define public_log_if(x) extern x
# endif
/** @defgroup _log_if Interfaces of LOG
* @{*/
//public_log_if( log_t *g_log;)
public_log_if( int logInit (void);)
public_log_if( void logRecord_mt(const char *file, const char *func, int line,int comp, int level, const char *format, ...);)
public_log_if( void logRecord(const char *file, const char *func, int line,int comp, int level, const char *format, ...);)
public_log_if( int set_comp_log(int component, int level, int verbosity, int interval);)
public_log_if( int set_log(int component, int level, int interval);)
public_log_if( void set_glog(int level, int verbosity);)
public_log_if( void set_log_syslog(int enable);)
public_log_if( void set_log_onlinelog(int enable);)
public_log_if( void set_log_filelog(int enable);)
public_log_if( void set_component_filelog(int comp);)
public_log_if( int map_str_to_int(mapping *map, const char *str);)
public_log_if( char *map_int_to_str(mapping *map, int val);)
public_log_if( void logClean (void); )
public_log_if( int is_newline( char *str, int size);)
public_log_if( void *log_thread_function(void * list);)
/* @}*/
#ifdef __cplusplus
}
#endif
#endif
// LTS: kept this file for compatibility
// this file was probably a trial to separate internal functions and external ones
// but it has never been finished, most source code include directly log.h (not log_if.h)
#include "log.h"
......@@ -75,101 +75,6 @@
#include "UTIL/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
#define DEBUG_REALTIME 1
#if DEBUG_REALTIME
typedef struct latency_stat {
uint64_t counter;
uint64_t stat1100;
uint64_t stat1200;
uint64_t stat1500;
uint64_t stat2000;
uint64_t stat3000;
} latency_stat_t;
static inline void saif_meas(int frame_rx) {
static latency_stat_t __thread latency_stat;
static struct timespec __thread last= {0};
struct timespec now;
clock_gettime(CLOCK_MONOTONIC_RAW, &now);
if ( last.tv_sec ) {
uint64_t diffTime = ((uint64_t)now.tv_sec *1000 *1000 *1000 + now.tv_nsec) -
((uint64_t)last.tv_sec *1000 *1000 *1000 + last.tv_nsec);
diffTime/=1000;
latency_stat.counter++;
if ( diffTime >= 1100 ) {
if (diffTime < 1200 )
latency_stat.stat1100++;
else if ( diffTime < 1500 )
latency_stat.stat1200++;
else if ( diffTime < 2000 )
latency_stat.stat1500++;
else if ( diffTime < 3000 )
latency_stat.stat2000++;
else
latency_stat.stat3000++;
}
if ( diffTime>=1100 || latency_stat.counter%20000==0 ) {
time_t current=time(NULL);
LOG_W(HW,
"%.2f delay=%llu Period stats %2.6f%% below 100µs\ncumul of events: 1100=%ld 1200=%ld 1500=%ld 2000=%ld >3000=%ld - (frame_rx=%d) - %s",
now.tv_sec+(double)now.tv_nsec/1e9,
diffTime,
(latency_stat.counter-latency_stat.stat1100-latency_stat.stat1200-
latency_stat.stat1500-latency_stat.stat2000-latency_stat.stat3000)/
(float)latency_stat.counter *100,
latency_stat.stat1100, latency_stat.stat1200,
latency_stat.stat1500, latency_stat.stat2000,
latency_stat.stat3000,
frame_rx, ctime(&current));
fflush(stdout);
}
}
last=now;
}
typedef struct m {
unsigned long long iterations;
unsigned long long sum;
unsigned long long maxArray[11];
} Meas;
void printMeas(char * txt, Meas *M, int period) {
if (M->iterations%period == 0 ) {
char txt2[512];
sprintf(txt2,"%s avg=%llu, iterations=%llu, max=%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu/%llu\n",
txt, M->sum/M->iterations,M->iterations,
M->maxArray[1],M->maxArray[2], M->maxArray[3],M->maxArray[4],
M->maxArray[5], M->maxArray[6],M->maxArray[7], M->maxArray[8],M->maxArray[9],M->maxArray[10]);
LOG_W(PHY,txt2);
}
}
int cmpint(const void* a, const void* b) {
unsigned long long* aa=(unsigned long long*)a;
unsigned long long* bb=(unsigned long long*)b;
return (int)(*aa-*bb);
}
void updateTimes(unsigned long long start, Meas *M, int period, char * txt) {
unsigned long long end=rdtsc();
long long diff=(end-start)/(cpuf*1000);
M->maxArray[0]=diff;
M->sum+=diff;
M->iterations++;
qsort(M->maxArray, 11, sizeof(unsigned long long), cmpint);
printMeas(txt,M,period);
}
#else
#define check(a) do {} while (0)
#define saif_meas(a) do {} while (0)
#define update_max_times(a,b) do {} while (0)
#define print_meas(a,b) do {} while (0)
#endif
/* End of Changed by SYRTEM */
#define FRAME_PERIOD 100000000ULL
......@@ -742,9 +647,10 @@ static void *UE_thread_rxn_txnp4(void *arg) {
instance_cnt_rxtx=proc->subframe_rx;
AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,"");
static __thread Meas t2= {0}, t3= {0};
unsigned long long current=rdtsc();
updateTimes(proc->gotIQs, &t2, 10000, "saif: Delay to wake up UE_Thread_Rx (case 2)");
initRefTimes(t2);
initRefTimes(t3);
pickTime(current);
updateTimes(proc->gotIQs, &t2, 10000, "Delay to wake up UE_Thread_Rx (case 2)");
// Process Rx data for one sub-frame
lte_subframe_t sf_type = subframe_select( &UE->frame_parms, proc->subframe_rx);
......@@ -812,7 +718,7 @@ static void *UE_thread_rxn_txnp4(void *arg) {
(UE->frame_parms.frame_type == TDD))
if (UE->mode != loop_through_memory)
phy_procedures_UE_S_TX(UE,0,0,no_relay);
updateTimes(current, &t3, 10000, "saif: Delay to process sub-frame (case 3)");
updateTimes(current, &t3, 10000, "Delay to process sub-frame (case 3)");
}
......@@ -1002,15 +908,15 @@ void *UE_thread(void *arg) {
if ( first_symbols <0 )
LOG_E(PHY,"can't compensate: diff =%d\n", first_symbols);
}
unsigned long long gotIQs=rdtsc();
pickTime(gotIQs);
// operate on thread sf mod 2
AssertFatal(pthread_mutex_lock(&proc->mutex_rxtx) ==0,"");
if(sub_frame == 0) {
UE->proc.proc_rxtx[0].frame_rx++;
UE->proc.proc_rxtx[1].frame_rx++;
}
UE->proc.proc_rxtx[0].gotIQs=gotIQs;
UE->proc.proc_rxtx[1].gotIQs=gotIQs;
UE->proc.proc_rxtx[0].gotIQs=readTime(gotIQs);
UE->proc.proc_rxtx[1].gotIQs=readTime(gotIQs);
proc->subframe_rx=sub_frame;
proc->subframe_tx=(sub_frame+4)%10;
proc->frame_tx = proc->frame_rx + (proc->subframe_rx>5?1:0);
......@@ -1020,12 +926,10 @@ void *UE_thread(void *arg) {
AssertFatal (pthread_cond_signal(&proc->cond_rxtx) ==0 ,"");
AssertFatal(pthread_mutex_unlock(&proc->mutex_rxtx) ==0,"");
static __thread Meas t1= {0};
static unsigned long long lastTime=0;
if ( lastTime != 0 )
updateTimes(lastTime, &t1, 20000, "saif: Delay between two IQ acquisitions (case 1)");
lastTime=rdtsc();
saif_meas(proc->frame_rx);
initRefTimes(t1);
initStaticTime(lastTime);
updateTimes(lastTime, &t1, 20000, "Delay between two IQ acquisitions (case 1)");
pickStaticTime(lastTime);
} else {
printf("Processing subframe %d",proc->subframe_rx);
......
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