diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d1067b210c158257f8ab9edb4c5821eafefd1743..ac6fbb2c8ebc86c4cb8fdd7e8c527850a1a9b603 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -241,6 +241,22 @@ build-codec-linux-make: - *print-common-info - make -j +# ensure that codec builds on linux with instrumentation active +build-codec-linux-instrumented-make: + rules: + - if: $CI_PIPELINE_SOURCE == 'web' + - if: $CI_PIPELINE_SOURCE == 'push' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "main" # only have MR pipelines for MRs to main + - if: $CI_PIPELINE_SOURCE == 'schedule' + - if: $CI_PIPELINE_SOURCE == 'push' + when: never + extends: + - .build-job-linux + script: + - *print-common-info + - sed -i".bak" "s/\/\*#define WMOPS 1\*\//#define WMOPS 1/g" lib_com/count.h + - make -j + # --------------------------------------------------------------- # Short test jobs # --------------------------------------------------------------- diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index c885d6c395e6238edc6481f8cf4b56faab2c1b21..728f4cd51614e21d2ae7815342bf37b674078423 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -154,6 +154,7 @@ + diff --git a/apps/decoder.c b/apps/decoder.c index db8af1b8eeafb507a4228c0dc0d51adede356476..0c57e2e4bc4b025629a5c49639a93a9c2d8897e6 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -45,6 +45,7 @@ #include "rotation_file_reader.h" #include "vector3_pair_file_reader.h" #include "wmc_auto.h" +#include "stl.h" #define WMC_TOOL_SKIP @@ -53,7 +54,7 @@ * Local constants *------------------------------------------------------------------------------------------*/ -#if !defined( WMOPS ) +#if !defined( WMOPS_FLT ) static #endif int32_t frame = 0; /* Counter of frames */ @@ -160,11 +161,15 @@ int main( IVAS_RENDER_FRAMESIZE asked_frame_size; int16_t run_unit_tests = 0; -#ifdef WMOPS +#ifdef WMOPS_FLT reset_wmops(); reset_mem( USE_BYTES ); #endif - +#if ( WMOPS ) +#ifndef DONT_COUNT + BASOP_init +#endif +#endif /*------------------------------------------------------------------------------------------* * Parse command-line arguments *------------------------------------------------------------------------------------------*/ @@ -566,7 +571,6 @@ int main( /*-----------------------------------------------------------------* * Decoding *-----------------------------------------------------------------*/ - if ( arg.voipMode ) { error = decodeVoIP( arg, hBsReader, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, hIvasDec ); @@ -601,7 +605,11 @@ int main( mainFailed = false; /* This will stay set to true if cleanup is reached via a goto due to an error */ cleanup: - +#ifndef DONT_COUNT + /* end of WMOPS counting */ + BASOP_end + BASOP_end_noprint +#endif free( pcmBuf ); if ( arg.hrtfReaderEnabled ) @@ -628,7 +636,7 @@ cleanup: fprintf( stderr, "\nError while closing file: %s\nContinuing...\n\n", arg.inputBitstreamFilename ); } -#ifdef WMOPS +#ifdef WMOPS_FLT print_wmops(); print_mem( NULL ); #endif @@ -1505,6 +1513,7 @@ static ivas_error decodeG192( IVAS_VECTOR3 Pos[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES] = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }; int16_t vec_pos_update, vec_pos_len; + for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; ++i ) { ismWriters[i] = NULL; @@ -1526,10 +1535,11 @@ static ivas_error decodeG192( delayNumSamples_orig[0] = -1; -#ifdef WMOPS +#ifdef WMOPS_FLT reset_stack(); reset_wmops(); #endif + nSamplesAvailableNext = 0; vec_pos_update = 0; @@ -1551,11 +1561,9 @@ static ivas_error decodeG192( * - Run the decoder * - Write the synthesized signal into output file *------------------------------------------------------------------------------------------*/ - while ( 1 ) { /* Read next frame if not enough samples availble */ - /* reference vector */ if ( arg.enableReferenceVectorTracking && vec_pos_update == 0 ) { @@ -1671,7 +1679,6 @@ static ivas_error decodeG192( goto cleanup; } } - if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, ( pcmBuf + nOutChannels * nSamplesRendered ), &nSamplesRendered_loop, &needNewFrame ) ) != IVAS_ERR_OK ) { @@ -1682,6 +1689,7 @@ static ivas_error decodeG192( nSamplesToRender -= nSamplesRendered_loop; if ( needNewFrame ) { + frame++; if ( !arg.quietModeEnabled ) { @@ -1691,6 +1699,7 @@ static ivas_error decodeG192( } while ( nSamplesRendered < nOutSamples && error == IVAS_ERR_OK ); + if ( error == IVAS_ERR_END_OF_FILE ) { break; @@ -1783,7 +1792,7 @@ static ivas_error decodeG192( } } vec_pos_update = ( vec_pos_update + 1 ) % vec_pos_len; -#ifdef WMOPS +#ifdef WMOPS_FLT if ( vec_pos_update == 0 ) { update_wmops(); @@ -1792,9 +1801,18 @@ static ivas_error decodeG192( export_mem( "mem_analysis.csv" ); #endif } +#endif +#ifdef WMOPS +#ifndef DONT_COUNT + if ( vec_pos_update == 0 ) + { + /* update WMPOS counting (end of frame) */ + BASOP_frame_update(); + } + +#endif #endif } - /*------------------------------------------------------------------------------------------* * Flush what is still left in the VoIP Buffers.... *------------------------------------------------------------------------------------------*/ @@ -1915,7 +1933,12 @@ static ivas_error decodeG192( } } } - +#ifdef WMOPS +#ifndef DONT_COUNT + /* update WMPOS counting (end of frame) */ + BASOP_frame_update(); +#endif +#endif frame++; if ( !arg.quietModeEnabled ) { @@ -2163,7 +2186,7 @@ static ivas_error decodeVoIP( fprintf( stdout, "\n-- Start the decoder (quiet mode) --\n\n" ); } -#ifdef WMOPS +#ifdef WMOPS_FLT reset_stack(); reset_wmops(); #endif @@ -2445,8 +2468,13 @@ static ivas_error decodeVoIP( vec_pos_update = ( vec_pos_update + 1 ) % vec_pos_len; frame++; systemTime_ms += systemTimeInc_ms; - #ifdef WMOPS +#ifndef DONT_COUNT + /* update WMPOS counting (end of frame) */ + BASOP_frame_update(); +#endif +#endif +#ifdef WMOPS_FLT update_mem(); update_wmops(); #endif diff --git a/apps/encoder.c b/apps/encoder.c index 3b77f5a312d98f4694aa5a43a7c161e92f11d0f6..6b110851e60de7a8bfbe87270b199624881f9165 100644 --- a/apps/encoder.c +++ b/apps/encoder.c @@ -39,6 +39,7 @@ #include "jbm_file_reader.h" #include "masa_file_reader.h" #include "wmc_auto.h" +#include "stl.h" #define WMC_TOOL_SKIP diff --git a/lib_com/count.c b/lib_com/count.c index edb33a24d6c4eb1be423d7e5f5b79924a28434ae..2ee28cee4245744970c120e0806b48fe4ee2af58 100644 --- a/lib_com/count.c +++ b/lib_com/count.c @@ -47,14 +47,17 @@ #include #include #include "stl.h" - +#include #ifdef WMOPS static double frameRate = FRAME_RATE; /* default value : 10 ms */ #endif /* ifdef WMOPS */ #ifdef WMOPS /* Global counter variable for calculation of complexity weight */ +/* Some enhancement written by Vail., GJR and M.Mul. during EVS time */ + BASIC_OP multiCounter[MAXCOUNTERS]; +BASIC_OP glob_multiCounter; int currCounter = 0; /* Zero equals global counter */ #endif /* ifdef WMOPS */ @@ -320,6 +323,13 @@ Word32 DeltaWeightedOperation (void); #ifdef WMOPS /* Counters for separating counting for different objects */ +/* FROM_EVS_DEV */ + /** + maxCounter: current number of counters. Each scope initialized with BASOP_sub_start() gets a own counter assigned. + objectName: Name of each counter passed to BASOP_sub_start(). + fwc_corr: + nbTimeObjectIsCalled: number of times a counter (object) is referenced in the current frame. + */ static int maxCounter = 0; static char *objectName[MAXCOUNTERS + 1]; @@ -327,13 +337,46 @@ static char *objectName[MAXCOUNTERS + 1]; static Word16 fwc_corr[MAXCOUNTERS + 1]; static long int nbTimeObjectIsCalled[MAXCOUNTERS + 1]; -#define NbFuncMax 1024 -static Word16 funcid[MAXCOUNTERS], nbframe[MAXCOUNTERS]; -static Word32 glob_wc[MAXCOUNTERS], wc[MAXCOUNTERS][NbFuncMax]; -static float total_wmops[MAXCOUNTERS]; +#define NbFuncMax (4096) + +/** + funcid: current function call for each counter + bc : best case for each counter and function call + wc : worst case for each counter and function call + nbframe: number of frames for each counter. + glob_bc: global best case self time for each counter for current frame. + glob_wc: global worst case self time for each counter for current frame. + glob_sum_curr: global cummulative time for each counter for current frame. + glob_sum_bc: global best case cummulative time for each counter for current frame. + glob_sum_wc: global worst case cummulative time for each counter for current frame. + + total_wmops: total wmops self time for each counter for current frame. + total_sum: total wmops cummulative time for each counter for current frame. + LastWOper: values used for WMOPS deltas + */ + +static Word32 funcid[MAXCOUNTERS], nbframe[MAXCOUNTERS], nbcalls[MAXCOUNTERS]; +static Word32 glob_bc[MAXCOUNTERS], glob_wc[MAXCOUNTERS], bc[MAXCOUNTERS][NbFuncMax], wc[MAXCOUNTERS][NbFuncMax]; +static float total_wmops[MAXCOUNTERS]; static Word32 LastWOper[MAXCOUNTERS]; +/* FROM_EVS_DEV */ +static float total_sum[MAXCOUNTERS]; +static Word16 call_tree[MAXCOUNTERS][MAXCOUNTERS]; +static int sum_curr[MAXCOUNTERS+1]; +static int sum_bc[MAXCOUNTERS+1]; +static int sum_wc[MAXCOUNTERS+1]; +static int glob_sum_curr[MAXCOUNTERS+1]; +static int glob_sum_bc[MAXCOUNTERS+1]; +static int glob_sum_wc[MAXCOUNTERS+1]; +#if MAX_CALLERS_SAVED_FRAMES +#define MAX_CALLERS_PRINT 20 +static float callers_frames[MAX_CALLERS_SAVED_FRAMES+1][MAXCOUNTERS+1]; +static int callers_frames_nos[MAX_CALLERS_SAVED_FRAMES]; +static float callers_totals[MAX_CALLERS_SAVED_FRAMES]; +#endif + #endif /* ifdef WMOPS */ @@ -427,9 +470,15 @@ static Word32 WMOPS_frameStat (void) { Word32 tot; tot = TotalWeightedOperation (); - if (tot > glob_wc[currCounter]) - glob_wc[currCounter] = tot; + if ( tot > glob_wc[currCounter] ) + { + glob_wc[currCounter] = tot; + } + if ( tot < glob_bc[currCounter] ) + { + glob_bc[currCounter] = tot; + } /* check if fwc() was forgotten at end of last frame */ if (tot > LastWOper[currCounter]) { if (!fwc_corr[currCounter]) { @@ -515,6 +564,13 @@ void Init_WMOPS_counter (void) { glob_wc[currCounter] = 0; nbframe[currCounter] = 0; total_wmops[currCounter] = 0.0; + for (i = 0; i < NbFuncMax; i++) + { + bc[currCounter][i] = (Word32)MAX_32; + } + glob_bc[currCounter] = MAX_32; + nbcalls[currCounter] = 0; + total_sum[currCounter] = 0.0; /* initially clear all counters */ WMOPS_clearMultiCounter (); @@ -524,24 +580,45 @@ void Init_WMOPS_counter (void) { /* Following line is useful for incrIf(), see control.h */ call_occurred = 1; funcId_where_last_call_to_else_occurred = MAXCOUNTERS; + + sum_bc[currCounter] = MAX_32; + sum_wc[currCounter] = 0; + sum_curr[currCounter] = 0; + for (i = 0; i < MAXCOUNTERS; i++) + { + call_tree[currCounter][i] = -1; + } + + glob_sum_curr[currCounter] = 0; + glob_sum_wc[currCounter] = 0; + glob_sum_bc[currCounter] = MAX_32; + #endif /* ifdef WMOPS */ } -void Reset_WMOPS_counter (void) { +Word32 Reset_WMOPS_counter(void) { #if WMOPS Word32 tot = WMOPS_frameStat (); /* increase the frame counter --> a frame is counted WHEN IT BEGINS */ nbframe[currCounter]++; - + /* Call counter */ + nbcalls[currCounter] += funcid[currCounter]; /* add wmops used in last frame to count, then reset counter (in first frame, this is a no-op */ total_wmops[currCounter] += (float) (tot * frameRate); + total_sum[currCounter] += (float)((glob_sum_curr[currCounter]) * frameRate); /* clear counter before new frame starts */ WMOPS_clearMultiCounter (); LastWOper[currCounter] = 0; funcid[currCounter] = 0; /* new frame, set function id to zero */ + + glob_sum_curr[currCounter] = 0; + sum_curr[currCounter] = 0; + return tot; +#else + return 0; #endif /* ifdef WMOPS */ } @@ -555,12 +632,20 @@ Word32 fwc (void) { if (tot > wc[currCounter][funcid[currCounter]]) wc[currCounter][funcid[currCounter]] = tot; - funcid[currCounter]++; - return (tot); + if (tot < bc[currCounter][funcid[currCounter]]) + bc[currCounter][funcid[currCounter]] = tot; -#else /* ifdef WMOPS */ - return 0; /* Dummy */ + funcid[currCounter]++; + /*make sure that BASOP_frame_update(); is put at the end of the main loop*/ + if (funcid[currCounter] >= NbFuncMax) + { + printf("to many function calls\n"); + } + assert(funcid[currCounter] < NbFuncMax); + return (tot); +#else + return 0; #endif /* ifdef WMOPS */ } @@ -596,8 +681,7 @@ void WMOPS_output (Word16 dtx_mode) { #endif /* ifdef WMOPS */ } - -void WMOPS_output_avg (Word16 dtx_mode, Word32 * tot_wm, Word16 * num_frames) { +void WMOPS_output_avg (Word16 dtx_mode, Word32 * tot_wm, Word32 * num_frames) { #if WMOPS Word16 i; Word32 tot, tot_wc; @@ -767,6 +851,586 @@ void generic_WMOPS_output (Word16 dtx_mode, char *test_file_name) { (void)test_file_name; #endif /* ifdef WMOPS */ } +/* FROM_EVS_DEV */ + +#define MAX_STACK 64 +static int stack[MAX_STACK]; +static int sptr; +static int sum_stack[MAX_STACK]; + +/* jdr 20120117: add FLC similar functions */ +void BASOP_frame_update(void) +{ +#if WMOPS + int i, current; +#if MAX_CALLERS_SAVED_FRAMES + int k; +#endif + float total = 0.0f; + +#ifdef DEBUG + { + static int sptr_target=-2; + + if (sptr_target == -2) { + sptr_target = sptr; + } else { + if (sptr_target != sptr) { + fprintf(stderr, "BASOP_sub_start/BASOP_sub_end imbalance detected!!!\n"); + sptr_target = sptr; + } + } + } +#endif + + /* Get current counter */ + current = readCounterId(); + + /* Update global operation counters */ + for (i=1; i<=maxCounter; i++) + { + int j; + + for (j=0; j< (int)(sizeof(BASIC_OP)/sizeof(UWord32)); j++) + { + ((UWord32*)&glob_multiCounter)[j] += ((UWord32*)&multiCounter[i])[j]; + } + } + +#if MAX_CALLERS_SAVED_FRAMES + /* Reset all counters */ + for (i=1; i<=maxCounter; i++) + { + callers_frames[0][i] = 0.0f; + } +#endif + /* Reset all counters */ + for (i=1; i<=maxCounter; i++) + { + if (current != i && funcid[i] > 0) { + setCounter(i); + + glob_sum_curr[currCounter] += sum_curr[currCounter]; + + if (glob_sum_curr[currCounter] > glob_sum_wc[currCounter]) { + glob_sum_wc[currCounter] = glob_sum_curr[currCounter]; + } + if (glob_sum_curr[currCounter] < glob_sum_bc[currCounter]) { + glob_sum_bc[currCounter] = glob_sum_curr[currCounter]; + } +#if MAX_CALLERS_SAVED_FRAMES + /* Keep a Copy before it is Reset */ + callers_frames[0][currCounter] = (float)Reset_WMOPS_counter(); + total += callers_frames[0][currCounter]; +#else + total += (float)Reset_WMOPS_counter(); +#endif + } + } + +#if MAX_CALLERS_SAVED_FRAMES + /* Keep Callers for this Worst Case Frame */ + /* Select Slot to Use (Slot 0 is the Current) */ + k = 0; + for (i=k+1; i callers_totals[k]) + { + k+=1; + /* Save Info of Callers */ + for (i=1; i<=maxCounter; i++) + { + callers_frames[k][i] = callers_frames[0][i]; + } + if (i < MAXCOUNTERS) + callers_frames[k][i] = -1; + /* Save Total */ + callers_totals[k-1] = total; + /* Save Frame Number */ + callers_frames_nos[k-1] = nbframe[0]; + } +#endif + if (total < glob_bc[0]) { + glob_bc[0] = (Word32) total; + } + if (total > glob_wc[0]) { + glob_wc[0] = (Word32) total; + + } + /* Restore current counter */ + setCounter(current); + + nbframe[0] ++; +#endif /* if WMOPS */ +} + +void printStack(char *text, char* Id) +{ +#if WMOPS + int i; + if (!Id) return; + if (!strcmp("*", Id) || (!strcmp(Id,objectName[currCounter]))) + { + printf ("%s %s", text, objectName[currCounter]); + for (i=sptr-1; i>0; i--) { + printf(" <- %s", objectName[stack[i]]); + } + printf("\n"); + } +#else + printf("%s %s\n", text, Id ? Id : "(no name)"); +#endif +} + +void BASOP_push_wmops (const char *label) +{ +#if WMOPS + int new_flag, prev_counter; + int i, j; + + /* Check if new counter label */ + new_flag = 1; + for (i = 1; i <= maxCounter; i++) + { + if (strcmp(objectName[i], label) == 0) + { + new_flag = 0; + break; + } + } + + prev_counter = readCounterId(); + + /* Configure new record */ + if (new_flag) + { + i = (int)getCounterId(label); + setCounter(i); + Init_WMOPS_counter(); + } + else + { + setCounter(i); + } + + + /* Push current context onto stack */ + if (currCounter >= 0) + { + if (sptr >= MAX_STACK) + { + fprintf (stderr, "\r push_wmops(): stack exceeded, try inreasing MAX_STACK\n"); + exit (-1); + } + stack[sptr++] = prev_counter; + + /* Reset accumulated WMOPS */ + sum_stack[sptr] = 0; + + /* update call tree */ + for (j = 0; j < MAXCOUNTERS; j++) + { + if (call_tree[i][j] == prev_counter) + { + break; + } + else if (call_tree[i][j] == -1) + { + call_tree[i][j] = (Word16)prev_counter; + break; + } + } + } + + /*wmops[currCounter].start_selfcnt = ops_cnt; + wmops[currCounter].start_cnt = ops_cnt; + nbTimeObjectIsCalled[currCounter]++;*/ + + incrementNbTimeObjectIsCalled(currCounter); + + sum_curr[currCounter] = 0; + +#ifdef DEBUG_COUNTER + printf("Entering: %s\n", readCounterIdName()); +#endif + +#endif /* if WMOPS */ +} + + +Word32 BASOP_pop_wmops (void) +{ +#if WMOPS + Word32 ops_cnt; + +#ifdef DEBUG_COUNTER + printf("Exiting: %s\n", readCounterIdName()); +#endif + + ops_cnt = fwc(); + + /* Get back previous context from stack */ + if (sptr > 0) + { + int prevCounter; + + sum_stack[sptr] += ops_cnt; + prevCounter = currCounter; + setCounter(stack[--sptr]); + sum_stack[sptr] += sum_stack[sptr+1]; + sum_curr[prevCounter] += sum_stack[sptr+1]; + } + else + { + /* current_record = -1; */ + setCounter(0); + } + + if (sum_curr[currCounter] > sum_wc[currCounter]) { + sum_wc[currCounter] = sum_curr[currCounter]; + } + if (sum_curr[currCounter] < sum_bc[currCounter]) { + sum_bc[currCounter] = sum_curr[currCounter]; + } + + return ops_cnt; +#else /* if WMOPS */ + return 0; +#endif /* if WMOPS */ +} + +Word32 BASOP_get_wops (void) +{ + return BASOP_pop_wmops(); +} + +#define FRAMES_PER_SECOND 50.0 +#define MILLION_CYCLES 1e6 +#define FAC (FRAMES_PER_SECOND/MILLION_CYCLES) + +static Word32 prom_cnt = 0; + +void WMOPS_destroy(void) +{ +#if WMOPS + int i; + + /* release the memory allocated for the objectName array */ + for (i = 0; i < MAXCOUNTERS+1; i++) + { + if (NULL != objectName[i]) + { + free(objectName[i]); + objectName[i] = NULL; + } + } + + maxCounter = 0; +#endif + + return; +} + + +void WMOPS_output_all(Word16 dtx_mode) +{ +#if WMOPS + float ops_cnt = 0.0f; + int i; + + char *sfmts = "%-40s %8s %8s %7s %7s\n"; + char *dfmts = "%-40s %8.2f %8.3f %7.3f %7.3f\n"; + char *sfmt = "%-40s %8s %8s %7s %7s %7s %7s %7s\n"; + char *dfmt = "%-40s %8.2f %8.3f %7.3f %7.3f %7.3f %7.3f %7.3f\n"; + + fprintf (stderr, "\nProgram Memory Analysis: %12.0f words\n", (float)prom_cnt); + /*fprintf (stderr, "\nInstruction Type Analysis (for worst case frame):\n\n");*/ + fprintf (stderr, "\nInstruction Type Analysis (for worst case frame number %ld):\n\n", (long int)nbframe[0]); /* added -- JPA */ + for (i = 0; i < (int)(sizeof(BasicOperationList)/sizeof(char*)) ; i++) + { + if ( ( (UWord32 *) &glob_multiCounter )[i] > 0) + fprintf (stderr, "\t%16s: %12d\n", BasicOperationList[i], ((UWord32*)&glob_multiCounter)[i]); + } + + fprintf (stderr, "\n\nWeighted MOPS Analysis:\n"); + fprintf (stderr, "%74s %23s\n", "|------ SELF ------|" + ,"|--- CUMULATIVE ---|"); + fprintf (stderr, sfmt, " routine", " calls", " min ", " max ", " avg ", " min ", " max ", " avg "); + fprintf (stderr, sfmt, " ------------------------", " ------", "------", "------", "------", "------", "------", "------"); + for (i = 1; i <= maxCounter; i++) + { + if ( nbcalls[i] > 0 ) + { + fprintf( stderr, dfmt, + objectName[i], + ( nbframe[i] == 0 ) ? 0 : (float) nbcalls[i] / (float) nbframe[0], + ( glob_bc[i] == 0 ) ? 0 : frameRate * (float) glob_bc[i], + ( glob_wc[i] == 0 ) ? 0 : frameRate * (float) glob_wc[i], + ( nbframe[i] == 0 ) ? 0 : (float) total_wmops[i] / (float) nbframe[i], + frameRate * ( glob_sum_bc[i] ), + frameRate * ( glob_sum_wc[i] ), + ( nbframe[i] == 0 ) ? 0 : (float) ( total_sum[i] / (float) nbframe[i] ) ); + /* frameRate*(glob_bc[i]+wmops_children_bc[i]), */ + /* frameRate*(glob_wc[i]+wmops_children_wc[i]), */ + /* (nbframe[i] == 0) ? 0 : (float)((total_wmops[i] + total_wmops_children[i]) /(float)nbframe[i])); */ + } + ops_cnt += total_wmops[i]; + } + + fprintf (stderr, sfmts, " -----------------", " ------", "------", "------", "------"); + if ( nbframe[i] > 0 ) + { + fprintf( stderr, dfmts, + "total", + (double) nbframe[0], + frameRate * glob_bc[0], + frameRate * glob_wc[0], + ( nbframe[0] == 0 ) ? 0 : ops_cnt / nbframe[0] ); + } +#if 0 + { + char *sfmtt = "%20s %4s %15s\n"; + char *dfmtt = "%20s %4d "; + + fprintf (stderr, "\nCall Tree:\n\n"); + fprintf (stderr, sfmtt, " function", "num", "called by: "); + fprintf (stderr, sfmtt, "---------------", "---", "--------------"); + + for (i = 1; i <= maxCounter; i++) + { + int j; + + fprintf (stderr, dfmtt, objectName[i], i); + for (j = 0; call_tree[i][j] != -1; j++) + { + if (j != 0) + { + fprintf (stderr, ", "); + } + fprintf (stderr, "%s", objectName[call_tree[i][j]]); + } + fprintf (stderr, "\n"); + + } + fprintf (stderr, sfmtt, "---------------", "---", "--------------"); + fprintf (stderr, "\n\n"); + } +#endif + +#if 0 + fprintf (stderr, "\n\n"); + for (i=1; i<=maxCounter; i++) + { + setCounter(i); + WMOPS_output(dtx_mode); + } +#else + (void)dtx_mode; +#endif + +#if MAX_CALLERS_SAVED_FRAMES + for (i = 1; i <= MAX_CALLERS_SAVED_FRAMES; i++) + { + int j, k, l, m; + const char *frame_rank[] = { "st", "nd", "rd", "th" }; + float current; + + k = 0; + for (j=k+1; j callers_totals[k]) + { /* Yes */ + k = j; + } + } + k+=1; + + fprintf(stderr, "\nActive Callers Report for %i%s Worst Case Frame #: %i\n", + i, i<=3?frame_rank[i-1]:frame_rank[3], + callers_frames_nos[k-1]); + /* Print up to 'MAX_CALLERS_PRINT' Callers */ + current = 0.0f; + for (l = 0; l < MAX_CALLERS_PRINT; l++) + { + /* Find Highest Complexity */ + m = 1; + for (j = m+1; j <= maxCounter; j++) + { + if (callers_frames[k][j] < 0) + break; + if (callers_frames[k][j] > callers_frames[k][m]) + m = j; + } + /* Done ? */ + if (callers_frames[k][m] == 0) + break; + fprintf(stderr, " %-52s %10.3f\n", objectName[m], callers_frames[k][m]*frameRate); + /* Count it */ + current += callers_frames[k][m]; + /* Mark as Done */ + callers_frames[k][m] = 0.0f; + } + /* Check if All Printed */ + if (current+0.001f < callers_totals[k-1]) + { + fprintf(stderr, " Only first %i Callers have been Printed!\n", MAX_CALLERS_PRINT); + fprintf(stderr, " %-52s %10.3f\n", "Total for non Printed", (callers_totals[k-1]-current)*frameRate); + } + fprintf(stderr, " %-52s %10.3f\n", "Total", callers_totals[k-1]*frameRate); + /* Mark as Done */ + callers_totals[k-1] = 0.0f; + } +#endif + WMOPS_destroy(); + +#endif /* if WMOPS */ +} +void WMOPS_output_all_std(Word16 dtx_mode) +{ +#if WMOPS + float ops_cnt = 0.0f; + int i; + + char *sfmts = "%-40s %8s %8s %7s %7s\n"; + char *dfmts = "%-40s %8.2f %8.3f %7.3f %7.3f\n"; + char *sfmt = "%-40s %8s %8s %7s %7s %7s %7s %7s\n"; + char *dfmt = "%-40s %8.2f %8.3f %7.3f %7.3f %7.3f %7.3f %7.3f\n"; + + fprintf (stdout, "\nProgram Memory Analysis: %12.0f words\n", (float)prom_cnt); + /*fprintf (stdout, "\nInstruction Type Analysis (for worst case frame):\n\n");*/ + fprintf (stdout, "\nInstruction Type Analysis (for worst case frame number %ld):\n\n", (long int)nbframe[0]); /* added -- JPA */ + if ( nbframe[0] > 0 ) + { + for ( i = 0; i < (int) ( sizeof( BasicOperationList ) / sizeof( char * ) ); i++ ) + { + if ( ((UWord32 *) &glob_multiCounter )[i] > 0 ) + fprintf( stdout, "\t%16s: %12d\n", BasicOperationList[i], ( (UWord32 *) &glob_multiCounter )[i] ); + } + } + fprintf (stdout, "\n\nWeighted MOPS Analysis:\n"); + fprintf (stdout, "%74s %23s\n", "|------ SELF ------|" + ,"|--- CUMULATIVE ---|"); + fprintf (stdout, sfmt, " routine", "calls/fr", " min ", " max ", " avg ", " min ", " max ", " avg "); + fprintf (stdout, sfmt, " ------------------------", " ------", "------", "------", "------", "------", "------", "------"); + for (i = 1; i <= maxCounter; i++) + { + fprintf( stdout, dfmt, + objectName[i], + ( nbframe[i] == 0 ) ? 0 : (float) nbcalls[i] / (float) nbframe[0], + ( glob_bc[i] == MAX_32 ) ? 0 : frameRate * (float) glob_bc[i], + ( glob_wc[i] == 0 ) ? 0 : frameRate * (float) glob_wc[i], + ( nbframe[i] == 0 ) ? 0 : (float) total_wmops[i] / (float) nbframe[i], + frameRate * ( glob_sum_bc[i] ), + frameRate * ( glob_sum_wc[i] ), + ( nbframe[i] == 0 ) ? 0 : (float) ( ( total_sum[i] ) / (float) nbframe[i] ) ); + /* frameRate*(glob_bc[i]+wmops_children_bc[i]), */ + /* frameRate*(glob_wc[i]+wmops_children_wc[i]), */ + /* (nbframe[i] == 0) ? 0 : (float)((total_sum[i]) /(float)nbframe[i])); */ + ops_cnt += total_wmops[i]; + } + + fprintf (stdout, sfmts, " -----------------", " ------", "------", "------", "------"); + if ( nbframe[0] > 0 ) + { + fprintf( stdout, dfmts, + "total", + (double) nbframe[0], + frameRate * glob_bc[0], + frameRate * glob_wc[0], + ( nbframe[0] == 0 ) ? 0 : ops_cnt / nbframe[0] ); + } +#if 0 + { + char *sfmtt = "%20s %4s %15s\n"; + char *dfmtt = "%20s %4d "; + + fprintf (stdout, "\nCall Tree:\n\n"); + fprintf (stdout, sfmtt, " function", "num", "called by: "); + fprintf (stdout, sfmtt, "---------------", "---", "--------------"); + + for (i = 1; i <= maxCounter; i++) + { + int j; + + fprintf (stdout, dfmtt, objectName[i], i); + for (j = 0; call_tree[i][j] != -1; j++) + { + if (j != 0) + { + fprintf (stdout, ", "); + } + fprintf (stdout, "%s", objectName[call_tree[i][j]]); + } + fprintf (stdout, "\n"); + + } + fprintf (stdout, sfmtt, "---------------", "---", "--------------"); + fprintf (stdout, "\n\n"); + } +#endif + +#if 0 + fprintf (stdout, "\n\n"); + for (i=1; i<=maxCounter; i++) + { + setCounter(i); + WMOPS_output(dtx_mode); + } +#else + (void)dtx_mode; +#endif + + + WMOPS_destroy(); + +#endif /* if WMOPS */ +} +void Reset_all_WMOPS_counter (void) +{ +#if WMOPS + int i; + int currCounterSave; + + currCounterSave = currCounter; + + for (i=2; i <= maxCounter; i++) + { + setCounter(i); + Init_WMOPS_counter(); + objectName[i] = 0; + } + + currCounter = currCounterSave; + maxCounter = 1; +#endif /* if WMOPS */ +} + +/* Returns the total min/max/avg WMOPS values like printed in BASOP_end(). */ +void BASOP_get_total_wmops(double *min, double *max, double *avg) +{ +#if WMOPS + if(min != NULL) + *min = frameRate * glob_bc[0]; + if(max != NULL) + *max = frameRate * glob_wc[0]; + if(avg != NULL) { + int i; + double ops_cnt = 0; + for(i = 1; i <= maxCounter; i++) + ops_cnt += total_wmops[i]; + *avg = (nbframe[0] == 0) ? 0 : ops_cnt / nbframe[0]; + } +#endif /* if WMOPS */ +} + /* end of file */ diff --git a/lib_com/count.h b/lib_com/count.h index 4e853d6f404f9ea254353428c403e1851bbd0847..76dfae2ed25f6e3f4bcf3b7d247c9b23389a0bc8 100644 --- a/lib_com/count.h +++ b/lib_com/count.h @@ -59,22 +59,11 @@ #ifndef _COUNT_H #define _COUNT_H "$Id$" -#if 0 -#define WMOPS 1 /* enable WMOPS profiling features */ -#undef WMOPS /* disable WMOPS profiling features */ -#endif -#define MAXCOUNTERS (256) +/*#define WMOPS 1*/ /* <<<- enable or disable WMOPS profiling features here */ -#define BASOP_sub_start(label) -#define BASOP_sub_end() -#define SUB_WMOPS_INIT(label) BASOP_sub_start(label) -#define END_SUB_WMOPS BASOP_sub_end() -#define BASOP_push_wmops(label) -#define BASOP_pop_wmops() -#define BASOP_end_noprint -#define BASOP_end -#define BASOP_init +#define MAXCOUNTERS (512) +#define MAX_CALLERS_SAVED_FRAMES 5 /* # of Frame for which WMOPS Complexity Details will be saved, 0 = Disabled */ int getCounterId (char *objectName); /* @@ -101,7 +90,14 @@ char *readCounterIdName (void); /* * Returns the current CounterId name. */ - +void printStack(char *text, char * Id); +/* + * print stack + * text: Any text to print initially + * Id: NULL, if no prints are wanted + * "*", if all prints are wanted (default) + * "pitch_ol" or any other function name + */ void incrementNbTimeObjectIsCalled (int counterId); /* @@ -126,8 +122,9 @@ void Init_WMOPS_counter (void); */ -void Reset_WMOPS_counter (void); -/* + +Word32 Reset_WMOPS_counter( void ); + /* * Resets the current counter group. */ @@ -140,7 +137,7 @@ void WMOPS_output (Word16 notPrintWorstWorstCase); * */ -void WMOPS_output_avg (Word16 dtx_mode, Word32 * tot_wm, Word16 * num_frames); +void WMOPS_output_avg (Word16 dtx_mode, Word32 * tot_wm, Word32 * num_frames); /* * same as WMOPS_output + returns the total wmops counter and the number of frames * to support the computation of global average. @@ -482,8 +479,13 @@ void generic_WMOPS_output (Word16 notPrintWorstWorstCase, char *test_file_name); * * notPrintWorstWorstCase : Same usage as in WMOPS_output(). */ +void WMOPS_output_all(Word16 dtx_mode); +void WMOPS_output_all_std(Word16 dtx_mode); - +/* + * free all allocated counter memory + */ +void WMOPS_destroy(void); #if 0 /* * Example of how count.h could be used. @@ -535,6 +537,50 @@ int main () { } #endif /* #if 0 */ +/* jdr 20120117: add FLC similar functions */ +/* mul 20130729: set BASOP_COUNT_SUBROUTINES to count on a per-BASOP_sub_start()/BASOP_sub_end() base; + otherwise, count only between BASOP_push_wmops(), BASOP_push_wmops() */ +#define BASOP_COUNT_SUBROUTINES +void BASOP_push_wmops (const char *label); +Word32 BASOP_pop_wmops (void); + +#define BASOP_init { setFrameRate(32000, 640); Init_WMOPS_counter(); /* 20ms frames */ } +#define BASOP_end { WMOPS_output_all_std(0); } +/*#define BASOP_end { WMOPS_output_all(0); }*/ +#define BASOP_end_noprint { WMOPS_destroy(); } + +#ifdef BASOP_COUNT_SUBROUTINES +#define BASOP_sub_start(label) { BASOP_push_wmops(label); } +#define BASOP_sub_end() { BASOP_pop_wmops(); } +#else +#define BASOP_sub_start(label) +#define BASOP_sub_end() +#endif + +void BASOP_frame_update(void); +void Reset_all_WMOPS_counter (void); + +Word32 BASOP_get_wops (void); + +/*! Returns the total min/max/avg WMOPS values like printed in BASOP_end(). */ +void BASOP_get_total_wmops(double *min, double *max, double *avg); + + +#define SUB_WMOPS_INIT( label ) BASOP_sub_start( label ) +#define END_SUB_WMOPS BASOP_sub_end() + + +#if !defined WMOPS_FL //&& defined WMOPS +#include +#define reset_wmops() BASOP_init +//extern int cntr_push_pop; +#define push_wmops( x ) { BASOP_push_wmops(x); } +#define pop_wmops() { BASOP_pop_wmops(); } +#define update_wmops() { BASOP_frame_update(); } +#define print_wmops() { WMOPS_output_all_std(0); } +#define update_mem(); +#endif + #endif /* _COUNT_H */ diff --git a/lib_com/move.h b/lib_com/move.h index 5b72a4c6aad0ba9c2ec3c3e3d4bc3fb1b16f8ac8..adf234ef4d4ce3690da8a8ac6cbd5a3358ba6c59 100644 --- a/lib_com/move.h +++ b/lib_com/move.h @@ -36,9 +36,14 @@ #ifndef _MOVE_H #define _MOVE_H - +#include "stl.h" /* BASOP -> FLC brigde: data move counting */ +#if (WMOPS) +extern BASIC_OP multiCounter[MAXCOUNTERS]; +extern int currCounter; +#endif /* ifdef WMOPS */ + static __inline void move16( void ) { #ifdef WMOPS @@ -55,6 +60,9 @@ static __inline void move32( void ) #ifdef ENH_64_BIT_OPERATOR static __inline void move64(void) { +#ifdef WMOPS + multiCounter[currCounter].move64++; +#endif /* if WMOPS */ } #endif /* #ifdef ENH_64_BIT_OPERATOR */ diff --git a/lib_com/options.h b/lib_com/options.h index 4c26a916280184d4f8deb4043de03711b8954009..192b4ccf1f625142d5498a5f811d9447f4748f21 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -40,6 +40,9 @@ #ifdef DEBUGGING #include "debug.h" #endif + +#include "stl.h" + /* clang-format off */ /* ################### Start compiler switches ######################## */ @@ -53,12 +56,15 @@ #pragma warning(disable:4310) /* cast truncates constant value this affects mainly constants tables*/ #endif -/*#define WMOPS*/ /* Activate complexity and memory counters */ +/*#define WMOPS 1 --> activation or deactivation in count.h*/ /* Activate FIXED-POINT complexity counters */ +/*#define DONT_COUNT */ /* To prevent the complexity counting */ + +#ifdef WMOPS_FLT /*#define WMOPS_PER_FRAME*/ /* Output per-frame complexity (writes one float value per frame to the file "wmops_analysis") */ /*#define WMOPS_DETAIL*/ /* Output detailed complexity printout for every function. Increases runtime overhead */ /*#define WMOPS_WC_FRAME_ANALYSIS*/ /* Output detailed complexity analysis for the worst-case frame */ /*#define MEM_COUNT_DETAILS*/ /* Output detailed memory analysis for the worst-case frame (writes to the file "mem_analysis.csv") */ - +#endif /* #################### End DEBUGGING switches ############################ */ diff --git a/lib_com/stl.h b/lib_com/stl.h index f87a5e8d459fda5dbdaefca59bd6208cfb871f13..cb5c7477c38c0f73e40820dcc59c45d3385c37f8 100644 --- a/lib_com/stl.h +++ b/lib_com/stl.h @@ -71,7 +71,8 @@ #include "options.h" /* note: needed until BASOP_NOGLOB is accepted */ #include "typedef.h" #include "basop32.h" -#include "wmc_auto.h" +#include "count.h" +//#include "wmc_auto.h" #include "move.h" #include "control.h" #include "oper_32b.h" diff --git a/lib_debug/wmc_auto.c b/lib_debug/wmc_auto.c index 029640a1dba8bce33cafd82907ef5bb5e5d5dabe..eafa02a2ea3c3d259927b7c8e00d207bcbedccd1 100644 --- a/lib_debug/wmc_auto.c +++ b/lib_debug/wmc_auto.c @@ -31,8 +31,7 @@ #define WMC_TOOL_SKIP /* Skip the instrumentation of this file, if invoked by accident */ -#ifdef WMOPS - +#ifdef WMOPS_FLT /*-------------------------------------------------------------------* * Complexity counting tool *--------------------------------------------------------------------*/ @@ -1921,6 +1920,7 @@ void print_mem( ROM_Size_Lookup_Table Const_Data_PROM_Table[] ) #endif /* WMOPS */ -#ifndef WMOPS +#ifndef WMOPS_FLT int cntr_push_pop = 0; /* global counter for checking balanced push_wmops()/pop_wmops() pairs when WMOPS is not activated */ +double ops_cnt; #endif diff --git a/lib_debug/wmc_auto.h b/lib_debug/wmc_auto.h index 9e20a4c7c8162126ead7cf45fbc8aab5f506c435..7d07a84a0e9383331f20e5181a548fca927d798f 100644 --- a/lib_debug/wmc_auto.h +++ b/lib_debug/wmc_auto.h @@ -37,7 +37,7 @@ #define NUM_INST 20 /* Total number of instruction types (in enum below) */ -#ifdef WMOPS +#ifdef WMOPS_FLT enum instructions { _ADD, @@ -570,8 +570,9 @@ void update_wmops( void ); void update_mem( void ); void print_wmops( void ); -#else /* WMOPS counting disabled */ - +#else /* WMOPS_FL counting disabled */ +#if 0 /* -> defined in count.h instead */ +#include #define reset_wmops() extern int cntr_push_pop; #define push_wmops( x ) ( cntr_push_pop++ ) @@ -579,6 +580,7 @@ extern int cntr_push_pop; #define update_wmops() ( assert( cntr_push_pop == 0 ) ) #define update_mem() #define print_wmops() +#endif #define ADD( x ) #define ABS( x ) @@ -622,7 +624,7 @@ extern int cntr_push_pop; #define msu( a, b, c ) ( ( a ) - ( b ) * ( c ) ) #endif -#ifndef WMOPS +#ifndef WMOPS_FLT /* DESACTIVATE the Counting Mechanism */ #define OP_COUNT_( op, n ) @@ -795,7 +797,7 @@ static int wmc_flag_ = 0; switch #define cost_( n ) OP_COUNT_WRAPPER2_( wmc_flag_ ? ( ADD_( n ), BRANCH_( n ), wmc_flag_ = 0 ) : 0 ); -#ifdef WMOPS +#ifdef WMOPS_FLT #define ACC 2 #define MUL 1 @@ -996,7 +998,7 @@ typedef enum #endif -#ifdef WMOPS +#ifdef WMOPS_FLT void *mem_alloc( const char *func_name, int func_lineno, size_t size, char *alloc_str ); void mem_free( const char *func_name, int func_lineno, void *ptr ); diff --git a/lib_dec/TonalComponentDetection_fx.c b/lib_dec/TonalComponentDetection_fx.c index ccc1421d6707f9bd56c2e2d8bbadde566d5cb41f..eb3ba5f016caffdb3a73e9a37828c0cebe510ca6 100644 --- a/lib_dec/TonalComponentDetection_fx.c +++ b/lib_dec/TonalComponentDetection_fx.c @@ -14,6 +14,7 @@ #include "rom_com.h" #include "basop_util.h" + /*---------------------------------------------------------------------* * Local function prototypes *---------------------------------------------------------------------*/ diff --git a/lib_dec/ivas_cpe_dec_fx.c b/lib_dec/ivas_cpe_dec_fx.c index 9ef02722c453bfd5a9a7660e561aff92fadfe29e..6bd6c2730afcb6155ffcf108c29d8b8dbd1ae231 100644 --- a/lib_dec/ivas_cpe_dec_fx.c +++ b/lib_dec/ivas_cpe_dec_fx.c @@ -442,7 +442,7 @@ ivas_error ivas_cpe_dec_fx( IF( st_ivas->hMCT ) { pop_wmops(); - + return error; } diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index de8edc2338dcbcea3076938695c67bc84710c375..8726f63d4e1ad5d93e42e67772f08a84cb946a8d 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -1678,6 +1678,7 @@ ivas_error ivas_jbm_dec_tc( pop_wmops(); + return IVAS_ERR_OK; } diff --git a/lib_dec/lib_dec_fx.c b/lib_dec/lib_dec_fx.c index f86a3b7776e9da3992dda12bff5eadf143d3436b..c77f1e33ed44237e99ea7833eb3f7b7897c617d8 100644 --- a/lib_dec/lib_dec_fx.c +++ b/lib_dec/lib_dec_fx.c @@ -905,7 +905,6 @@ ivas_error IVAS_DEC_GetSamples( { return error; } - /* JBM */ IF( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm ) {