michael@0: /*********************************************************************** michael@0: Copyright (c) 2006-2011, Skype Limited. All rights reserved. michael@0: Redistribution and use in source and binary forms, with or without michael@0: modification, are permitted provided that the following conditions michael@0: are met: michael@0: - Redistributions of source code must retain the above copyright notice, michael@0: this list of conditions and the following disclaimer. michael@0: - Redistributions in binary form must reproduce the above copyright michael@0: notice, this list of conditions and the following disclaimer in the michael@0: documentation and/or other materials provided with the distribution. michael@0: - Neither the name of Internet Society, IETF or IETF Trust, nor the michael@0: names of specific contributors, may be used to endorse or promote michael@0: products derived from this software without specific prior written michael@0: permission. michael@0: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" michael@0: AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE michael@0: IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE michael@0: ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE michael@0: LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR michael@0: CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF michael@0: SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS michael@0: INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN michael@0: CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) michael@0: ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE michael@0: POSSIBILITY OF SUCH DAMAGE. michael@0: ***********************************************************************/ michael@0: michael@0: #ifdef HAVE_CONFIG_H michael@0: #include "config.h" michael@0: #endif michael@0: michael@0: #include "debug.h" michael@0: #include "SigProc_FIX.h" michael@0: michael@0: #if SILK_TIC_TOC michael@0: michael@0: #ifdef _WIN32 michael@0: michael@0: #if (defined(_WIN32) || defined(_WINCE)) michael@0: #include /* timer */ michael@0: #else /* Linux or Mac*/ michael@0: #include michael@0: #endif michael@0: michael@0: unsigned long silk_GetHighResolutionTime(void) /* O time in usec*/ michael@0: { michael@0: /* Returns a time counter in microsec */ michael@0: /* the resolution is platform dependent */ michael@0: /* but is typically 1.62 us resolution */ michael@0: LARGE_INTEGER lpPerformanceCount; michael@0: LARGE_INTEGER lpFrequency; michael@0: QueryPerformanceCounter(&lpPerformanceCount); michael@0: QueryPerformanceFrequency(&lpFrequency); michael@0: return (unsigned long)((1000000*(lpPerformanceCount.QuadPart)) / lpFrequency.QuadPart); michael@0: } michael@0: #else /* Linux or Mac*/ michael@0: unsigned long GetHighResolutionTime(void) /* O time in usec*/ michael@0: { michael@0: struct timeval tv; michael@0: gettimeofday(&tv, 0); michael@0: return((tv.tv_sec*1000000)+(tv.tv_usec)); michael@0: } michael@0: #endif michael@0: michael@0: int silk_Timer_nTimers = 0; michael@0: int silk_Timer_depth_ctr = 0; michael@0: char silk_Timer_tags[silk_NUM_TIMERS_MAX][silk_NUM_TIMERS_MAX_TAG_LEN]; michael@0: #ifdef WIN32 michael@0: LARGE_INTEGER silk_Timer_start[silk_NUM_TIMERS_MAX]; michael@0: #else michael@0: unsigned long silk_Timer_start[silk_NUM_TIMERS_MAX]; michael@0: #endif michael@0: unsigned int silk_Timer_cnt[silk_NUM_TIMERS_MAX]; michael@0: opus_int64 silk_Timer_min[silk_NUM_TIMERS_MAX]; michael@0: opus_int64 silk_Timer_sum[silk_NUM_TIMERS_MAX]; michael@0: opus_int64 silk_Timer_max[silk_NUM_TIMERS_MAX]; michael@0: opus_int64 silk_Timer_depth[silk_NUM_TIMERS_MAX]; michael@0: michael@0: #ifdef WIN32 michael@0: void silk_TimerSave(char *file_name) michael@0: { michael@0: if( silk_Timer_nTimers > 0 ) michael@0: { michael@0: int k; michael@0: FILE *fp; michael@0: LARGE_INTEGER lpFrequency; michael@0: LARGE_INTEGER lpPerformanceCount1, lpPerformanceCount2; michael@0: int del = 0x7FFFFFFF; michael@0: double avg, sum_avg; michael@0: /* estimate overhead of calling performance counters */ michael@0: for( k = 0; k < 1000; k++ ) { michael@0: QueryPerformanceCounter(&lpPerformanceCount1); michael@0: QueryPerformanceCounter(&lpPerformanceCount2); michael@0: lpPerformanceCount2.QuadPart -= lpPerformanceCount1.QuadPart; michael@0: if( (int)lpPerformanceCount2.LowPart < del ) michael@0: del = lpPerformanceCount2.LowPart; michael@0: } michael@0: QueryPerformanceFrequency(&lpFrequency); michael@0: /* print results to file */ michael@0: sum_avg = 0.0f; michael@0: for( k = 0; k < silk_Timer_nTimers; k++ ) { michael@0: if (silk_Timer_depth[k] == 0) { michael@0: sum_avg += (1e6 * silk_Timer_sum[k] / silk_Timer_cnt[k] - del) / lpFrequency.QuadPart * silk_Timer_cnt[k]; michael@0: } michael@0: } michael@0: fp = fopen(file_name, "w"); michael@0: fprintf(fp, " min avg %% max count\n"); michael@0: for( k = 0; k < silk_Timer_nTimers; k++ ) { michael@0: if (silk_Timer_depth[k] == 0) { michael@0: fprintf(fp, "%-28s", silk_Timer_tags[k]); michael@0: } else if (silk_Timer_depth[k] == 1) { michael@0: fprintf(fp, " %-27s", silk_Timer_tags[k]); michael@0: } else if (silk_Timer_depth[k] == 2) { michael@0: fprintf(fp, " %-26s", silk_Timer_tags[k]); michael@0: } else if (silk_Timer_depth[k] == 3) { michael@0: fprintf(fp, " %-25s", silk_Timer_tags[k]); michael@0: } else { michael@0: fprintf(fp, " %-24s", silk_Timer_tags[k]); michael@0: } michael@0: avg = (1e6 * silk_Timer_sum[k] / silk_Timer_cnt[k] - del) / lpFrequency.QuadPart; michael@0: fprintf(fp, "%8.2f", (1e6 * (silk_max_64(silk_Timer_min[k] - del, 0))) / lpFrequency.QuadPart); michael@0: fprintf(fp, "%12.2f %6.2f", avg, 100.0 * avg / sum_avg * silk_Timer_cnt[k]); michael@0: fprintf(fp, "%12.2f", (1e6 * (silk_max_64(silk_Timer_max[k] - del, 0))) / lpFrequency.QuadPart); michael@0: fprintf(fp, "%10d\n", silk_Timer_cnt[k]); michael@0: } michael@0: fprintf(fp, " microseconds\n"); michael@0: fclose(fp); michael@0: } michael@0: } michael@0: #else michael@0: void silk_TimerSave(char *file_name) michael@0: { michael@0: if( silk_Timer_nTimers > 0 ) michael@0: { michael@0: int k; michael@0: FILE *fp; michael@0: /* print results to file */ michael@0: fp = fopen(file_name, "w"); michael@0: fprintf(fp, " min avg max count\n"); michael@0: for( k = 0; k < silk_Timer_nTimers; k++ ) michael@0: { michael@0: if (silk_Timer_depth[k] == 0) { michael@0: fprintf(fp, "%-28s", silk_Timer_tags[k]); michael@0: } else if (silk_Timer_depth[k] == 1) { michael@0: fprintf(fp, " %-27s", silk_Timer_tags[k]); michael@0: } else if (silk_Timer_depth[k] == 2) { michael@0: fprintf(fp, " %-26s", silk_Timer_tags[k]); michael@0: } else if (silk_Timer_depth[k] == 3) { michael@0: fprintf(fp, " %-25s", silk_Timer_tags[k]); michael@0: } else { michael@0: fprintf(fp, " %-24s", silk_Timer_tags[k]); michael@0: } michael@0: fprintf(fp, "%d ", silk_Timer_min[k]); michael@0: fprintf(fp, "%f ", (double)silk_Timer_sum[k] / (double)silk_Timer_cnt[k]); michael@0: fprintf(fp, "%d ", silk_Timer_max[k]); michael@0: fprintf(fp, "%10d\n", silk_Timer_cnt[k]); michael@0: } michael@0: fprintf(fp, " microseconds\n"); michael@0: fclose(fp); michael@0: } michael@0: } michael@0: #endif michael@0: michael@0: #endif /* SILK_TIC_TOC */ michael@0: michael@0: #if SILK_DEBUG michael@0: FILE *silk_debug_store_fp[ silk_NUM_STORES_MAX ]; michael@0: int silk_debug_store_count = 0; michael@0: #endif /* SILK_DEBUG */ michael@0: