| /******************************************************************************* |
| * Copyright (C) 2018 Cadence Design Systems, Inc. |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining |
| * a copy of this software and associated documentation files (the |
| * "Software"), to use this Software with Cadence processor cores only and |
| * not with any other processors and platforms, subject to |
| * the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included |
| * in all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
| * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
| * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
| * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
| * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| |
| ******************************************************************************/ |
| |
| #ifndef __XA_PROFILER_H__ |
| #define __XA_PROFILER_H__ |
| |
| #if !defined(PROFILE) && __XCC__ |
| #define PROFILE 1 |
| #endif |
| |
| #if !defined(PREFETCH_CTL) && __XCC__ |
| #define PREFETCH_CTL 1 |
| #endif |
| |
| #ifdef PROFILE |
| #include <xtensa/hal.h> |
| #include <sys/times.h> |
| |
| #include "xa_type_def.h" |
| #include "xa_timer.h" |
| |
| TRACE_TAG(MCPS,1); |
| |
| typedef struct XA_PROFILER { |
| #if 1 |
| unsigned long cstart; |
| unsigned long cstop; |
| unsigned long cycles; |
| unsigned long g_output_bytes; |
| unsigned long Peak; |
| unsigned long Sum; |
| |
| unsigned long sample_rate; |
| unsigned long channels; |
| unsigned long pcm_width; |
| #else |
| struct tms start; |
| struct tms stop; |
| double Peak; |
| double Sum; |
| long long cycles; |
| #endif |
| int Peak_frame; |
| int frame_count; |
| long long output_bytes; |
| long long total_cycles; |
| long long total_samples; |
| char *id; |
| } xa_profiler; |
| |
| extern xa_profiler prof; |
| |
| static inline void xa_compute_mcps(xa_profiler *p_prof, WORD32 samples_decoded, UWORD32 samp_freq, long long gen_strm_pos) |
| { |
| double Ave=0.0, Curr; |
| |
| if (samples_decoded <= 0) |
| return; |
| |
| p_prof->total_samples += samples_decoded; |
| p_prof->frame_count++; |
| |
| clock_t cycles = p_prof->cycles; |
| p_prof->total_cycles = 0; |
| Curr = ((double) cycles / samples_decoded * samp_freq / 1000000); |
| |
| if (p_prof->frame_count > 1) { |
| p_prof->Sum += Curr; |
| Ave = p_prof->Sum / (p_prof->frame_count-1); |
| |
| if (p_prof->Peak < Curr) { |
| p_prof->Peak = Curr; |
| p_prof->Peak_frame = (p_prof->frame_count); |
| } |
| } |
| |
| unsigned long long total_msec = |
| (unsigned long long)((double)p_prof->total_samples / samp_freq * 1000.0); |
| int msec = (int)(total_msec % 1000); |
| unsigned long long total_seconds = total_msec / 1000; |
| int seconds = (int)(total_seconds % 60); |
| int minutes = (int)(total_seconds / 60); |
| |
| #if 1 |
| TRACE(MCPS, _b("[%d] %d:%d.%d MCPS: %d Average: %d samples: %d\n"), |
| p_prof->frame_count, (uint32_t)minutes, (uint32_t)seconds, (uint32_t)msec, |
| (uint32_t)Curr, (uint32_t)Ave, samples_decoded); |
| #else |
| TRACE(MCPS, _b("[%d|%lld] %d:%02d.%03d MCPS: %.2f Average: %.2f Peak: %.2f @ [%d] %s\n"), |
| p_prof->frame_count, gen_strm_pos, minutes, seconds, msec, |
| Curr, Ave, p_prof->Peak, p_prof->Peak_frame, p_prof->id); |
| #endif |
| |
| /* reset counters */ |
| p_prof->g_output_bytes = 0; |
| p_prof->cycles = 0; |
| } |
| |
| #define INIT_XA_PROFILER(x, a) do { memset(&x, 0, sizeof(xa_profiler)); \ |
| x.sample_rate = 48000;\ |
| x.channels = 2;\ |
| x.pcm_width = 16;\ |
| x.id = a; } while(0) |
| |
| #define START_TIME_XA_PROFILER(x) do { set_ccount(0); \ |
| x.cstart=read_ccount(); } while(0) |
| #define STOP_TIME_XA_PROFILER(x) do { x.cstop =read_ccount(); \ |
| x.cycles += (x.cstop - x.cstart); } while(0) |
| #define COMPUTE_MHZ_XA_PROFILER(x, a, b, c) do { xa_compute_mcps(&x, a, b, c); } while(0) |
| #define SUMMARY_XA_PROFILER(x) do { fprintf(stdout,"\n%5s Peak MCPS = %f\n", x.id, x.Peak); \ |
| fprintf(stdout,"%5s Peak frame = %d\n", x.id, x.Peak_frame); \ |
| fprintf(stdout,"%5s Average MCPS = %f\n", x.id, (x.frame_count < 2) ? 0 : (x.Sum/(x.frame_count-1))); } while(0) |
| |
| #else |
| |
| typedef struct XA_PROFILER { |
| int place_holder; |
| } xa_profiler; |
| |
| #define INIT_XA_PROFILER(x, a) do {} while(0) |
| #define START_TIME_XA_PROFILER(x) do {} while(0) |
| #define STOP_TIME_XA_PROFILER(x) do {} while(0) |
| #define COMPUTE_MHZ_XA_PROFILER(x, a, b) do {} while(0) |
| #define SUMMARY_XA_PROFILER(x) do {} while(0) |
| #endif |
| |
| #ifdef PREFETCH_CTL |
| #define PREFETCH_AGGRESSIVE(x) do { x = xthal_set_cache_prefetch ((XTHAL_DCACHE_PREFETCH_HIGH | XTHAL_ICACHE_PREFETCH_HIGH)); \ |
| } while(0) |
| #define PREFETCH_RESTORE(x) do { xthal_set_cache_prefetch (x); } while(0) |
| #else |
| #define PREFETCH_AGGRESSIVE(x) do {} while(0) |
| #define PREFETCH_RESTORE(x) do {} while(0) |
| #endif |
| |
| #endif /* __XA_PROFILER_H__ */ |
| |