1 /*******************************************************************************
2 * Copyright (C) 2018 Cadence Design Systems, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to use this Software with Cadence processor cores only and
7 * not with any other processors and platforms, subject to
8 * the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included
11 * in all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
15 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
17 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
18 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
19 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 
21 ******************************************************************************/
22 
23 #ifndef __XA_PROFILER_H__
24 #define __XA_PROFILER_H__
25 
26 #if !defined(PROFILE) && __XCC__
27 #define PROFILE 1
28 #endif
29 
30 #if !defined(PREFETCH_CTL) && __XCC__
31 #define PREFETCH_CTL 1
32 #endif
33 
34 #ifdef PROFILE
35 #include <xtensa/hal.h>
36 #include <sys/times.h>
37 
38 #include "xa_type_def.h"
39 #include "xa_timer.h"
40 
41 TRACE_TAG(MCPS,1);
42 
43 typedef struct XA_PROFILER {
44 #if 1
45     unsigned long cstart;
46     unsigned long cstop;
47     unsigned long cycles;
48     unsigned long g_output_bytes;
49     unsigned long Peak;
50     unsigned long Sum;
51 
52     unsigned long sample_rate;
53     unsigned long channels;
54     unsigned long pcm_width;
55 #else
56     struct tms start;
57     struct tms stop;
58     double Peak;
59     double Sum;
60     long long cycles;
61 #endif
62     int Peak_frame;
63     int frame_count;
64     long long output_bytes;
65     long long total_cycles;
66     long long total_samples;
67     char *id;
68 } xa_profiler;
69 
70 extern xa_profiler prof;
71 
xa_compute_mcps(xa_profiler * p_prof,WORD32 samples_decoded,UWORD32 samp_freq,long long gen_strm_pos)72 static inline void xa_compute_mcps(xa_profiler *p_prof, WORD32 samples_decoded, UWORD32 samp_freq, long long gen_strm_pos)
73 {
74     double Ave=0.0, Curr;
75 
76     if (samples_decoded <= 0)
77         return;
78 
79     p_prof->total_samples += samples_decoded;
80     p_prof->frame_count++;
81 
82     clock_t cycles = p_prof->cycles;
83     p_prof->total_cycles = 0;
84     Curr = ((double) cycles / samples_decoded * samp_freq / 1000000);
85 
86     if (p_prof->frame_count > 1) {
87         p_prof->Sum += Curr;
88         Ave = p_prof->Sum / (p_prof->frame_count-1);
89 
90         if (p_prof->Peak < Curr) {
91             p_prof->Peak = Curr;
92             p_prof->Peak_frame = (p_prof->frame_count);
93         }
94     }
95 
96     unsigned long long total_msec =
97         (unsigned long long)((double)p_prof->total_samples / samp_freq * 1000.0);
98     int msec = (int)(total_msec % 1000);
99     unsigned long long total_seconds = total_msec / 1000;
100     int seconds = (int)(total_seconds % 60);
101     int minutes = (int)(total_seconds / 60);
102 
103 #if 1
104     TRACE(MCPS, _b("[%d] %d:%d.%d MCPS: %d Average: %d samples: %d\n"),
105         p_prof->frame_count, (uint32_t)minutes, (uint32_t)seconds, (uint32_t)msec,
106         (uint32_t)Curr, (uint32_t)Ave, samples_decoded);
107 #else
108     TRACE(MCPS, _b("[%d|%lld] %d:%02d.%03d MCPS: %.2f Average: %.2f Peak: %.2f @ [%d] %s\n"),
109         p_prof->frame_count, gen_strm_pos, minutes, seconds, msec,
110         Curr, Ave, p_prof->Peak, p_prof->Peak_frame, p_prof->id);
111 #endif
112 
113     /* reset counters */
114     p_prof->g_output_bytes = 0;
115     p_prof->cycles = 0;
116 }
117 
118 #define INIT_XA_PROFILER(x, a)                  do { memset(&x, 0, sizeof(xa_profiler)); \
119                                                      x.sample_rate = 48000;\
120                                                      x.channels = 2;\
121                                                      x.pcm_width = 16;\
122                                                      x.id = a; } while(0)
123 
124 #define START_TIME_XA_PROFILER(x)               do { set_ccount(0); \
125                                                      x.cstart=read_ccount(); } while(0)
126 #define STOP_TIME_XA_PROFILER(x)                do { x.cstop =read_ccount(); \
127                                                      x.cycles += (x.cstop - x.cstart); } while(0)
128 #define COMPUTE_MHZ_XA_PROFILER(x, a, b, c)        do { xa_compute_mcps(&x, a, b, c); } while(0)
129 #define SUMMARY_XA_PROFILER(x)                  do { fprintf(stdout,"\n%5s Peak MCPS = %f\n", x.id, x.Peak); \
130                                                      fprintf(stdout,"%5s Peak frame = %d\n", x.id, x.Peak_frame); \
131                                                      fprintf(stdout,"%5s Average MCPS = %f\n", x.id, (x.frame_count < 2) ? 0 : (x.Sum/(x.frame_count-1))); } while(0)
132 
133 #else
134 
135 typedef struct XA_PROFILER {
136     int place_holder;
137 } xa_profiler;
138 
139 #define INIT_XA_PROFILER(x, a)                  do {} while(0)
140 #define START_TIME_XA_PROFILER(x)               do {} while(0)
141 #define STOP_TIME_XA_PROFILER(x)                do {} while(0)
142 #define COMPUTE_MHZ_XA_PROFILER(x, a, b)        do {} while(0)
143 #define SUMMARY_XA_PROFILER(x)                  do {} while(0)
144 #endif
145 
146 #ifdef PREFETCH_CTL
147 #define PREFETCH_AGGRESSIVE(x)                  do { x = xthal_set_cache_prefetch ((XTHAL_DCACHE_PREFETCH_HIGH | XTHAL_ICACHE_PREFETCH_HIGH)); \
148                                                    } while(0)
149 #define PREFETCH_RESTORE(x)                     do { xthal_set_cache_prefetch (x); } while(0)
150 #else
151 #define PREFETCH_AGGRESSIVE(x)                  do {} while(0)
152 #define PREFETCH_RESTORE(x)                     do {} while(0)
153 #endif
154 
155 #endif /* __XA_PROFILER_H__ */
156 
157