1 /*---------------------------------------------------------------------------*
2 * comp_stats.c *
3 * *
4 * Copyright 2007, 2008 Nuance Communciations, Inc. *
5 * *
6 * Licensed under the Apache License, Version 2.0 (the 'License'); *
7 * you may not use this file except in compliance with the License. *
8 * *
9 * You may obtain a copy of the License at *
10 * http://www.apache.org/licenses/LICENSE-2.0 *
11 * *
12 * Unless required by applicable law or agreed to in writing, software *
13 * distributed under the License is distributed on an 'AS IS' BASIS, *
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
15 * See the License for the specific language governing permissions and *
16 * limitations under the License. *
17 * *
18 *---------------------------------------------------------------------------*/
19
20
21
22 #include "buildopt.h"
23 #include "pstdio.h"
24 #include "passert.h"
25 #include <time.h>
26 #include "comp_stats.h"
27 #include "portable.h"
28 #include "PFile.h"
29
30 #ifdef SET_RCSID
31 static const char *rcsid = 0 ? (const char *) &rcsid : "$Id: compstats now";
32 #endif
33
34 #if defined(__cplusplus)
35 extern "C"
36 {
37 #endif
38 COMP_STATS *comp_stats = NULL;
39 #if defined(__cplusplus)
40 }
41 #endif
42
43 /* create COMP_STATS object */
44
init_comp_stats(void)45 COMP_STATS *init_comp_stats(void)
46 {
47 static COMP_STATS c;
48
49 /*c = (COMP_STATS *) calloc( 1, sizeof( COMP_STATS ));*/
50 /*c = (COMP_STATS *) NEW( COMP_STATS, L("crec.comp_stats")); */
51
52 init_cs_clock(&c.overall_search);
53 init_cs_clock(&c.models);
54 init_cs_clock(&c.fsm_to_hmm);
55 init_cs_clock(&c.internal_hmm);
56 init_cs_clock(&c.hmm_to_fsm);
57 init_cs_clock(&c.epsilon);
58 init_cs_clock(&c.astar);
59 init_cs_clock(&c.prune);
60 init_cs_clock(&c.front_end);
61 init_cs_clock(&c.word_lookup);
62 init_cs_clock(&c.word_addition);
63 c.total_time = 0;
64 return &c;
65 }
66
67
dump_comp_stats(COMP_STATS * cs,PFile * fp)68 void dump_comp_stats(COMP_STATS *cs, PFile* fp)
69 {
70 if (getenv("HIDE_COMP_STATS"))
71 return;
72 #if !defined(_WIN32) && !defined(__vxworks)
73 if (clock() == (clock_t) - 1)
74 {
75 pfprintf(fp, "***WARNING: clock overrun!\n");
76 }
77 #endif
78 if (!cs) cs = comp_stats;
79
80 #ifdef SREC_ENGINE_VERBOSE_LOGGING
81 pfprintf(fp, "Total Time %5.2f Seconds\n", cs->total_time);
82 #endif
83 print_cs_clock(&cs->front_end, cs->total_time, fp, "Front end", "Frames");
84 print_cs_clock(&cs->overall_search, cs->total_time, fp, "Total Search", "Frames");
85 print_cs_clock(&cs->models, cs->total_time, fp, " Models", "Models");
86 print_cs_clock(&cs->internal_hmm, cs->total_time, fp, " Internal HMM", "HMMs");
87 print_cs_clock(&cs->fsm_to_hmm, cs->total_time, fp, " FSM to HMM", "FSM_Nodes");
88 print_cs_clock(&cs->prune, cs->total_time, fp, " Prune", "HMM States");
89 print_cs_clock(&cs->hmm_to_fsm, cs->total_time, fp, " HMM to FSM", "HMMS");
90 print_cs_clock(&cs->epsilon, cs->total_time, fp, " Epsilon", "FSM_Nodes");
91 print_cs_clock(&cs->astar, cs->total_time, fp, " Astar", "Utterances");
92 print_cs_clock(&cs->word_lookup, cs->total_time, fp, " WordLookup", "Words");
93 print_cs_clock(&cs->word_addition, cs->total_time, fp, " WordAdd'tn", "Pronunciations");
94 pfflush(fp);
95 }
96
97
print_cs_clock(CS_CLOCK * c,float num_seconds,PFile * fp,char * prompt,char * item_name)98 void print_cs_clock(CS_CLOCK *c, float num_seconds, PFile* fp, char *prompt, char *item_name)
99 {
100 if (c == NULL) return;
101 /* FPRINTF( fp, "%15.15s %8.2f. Per Second of speech: %6.2f ms, %6.2f calls, %6.2f (%d) %s\n",
102 prompt ? prompt : "",
103 c->total_time/c->clocks_per_msec,
104 (c->total_time/c->clocks_per_msec) / num_seconds,
105 c->ncalls / num_seconds,
106 c->item_count / num_seconds,
107 c->item_count,
108 item_name);*/
109 }
110
111
start_cs_clock(CS_CLOCK * c)112 void start_cs_clock(CS_CLOCK *c)
113 {
114 if (c == NULL) return;
115 #ifdef _WIN32
116 {
117 FILETIME dummy, kernelCPU, userCPU;
118 GetThreadTimes(GetCurrentThread(), &dummy, &dummy, &kernelCPU,
119 &userCPU);
120 c->last = kernelCPU.dwLowDateTime + ((__int64)kernelCPU.dwHighDateTime << 32) +
121 userCPU.dwLowDateTime + ((__int64)userCPU.dwHighDateTime << 32);
122 }
123 #elif defined(__vxworks)
124 /* Should use a portable clock() */
125 /* WxWorks: clock() always returns -1. VxWorks does not track per-task time or system idle time.
126 There is no method of determining how long a task or the entire system has been doing work.
127 tickGet( ) can be used to query the number of system ticks since system start.
128 clock_gettime( ) can be used to get the current clock time.
129 */
130 c->last = tickGet();
131 #else
132 c->last = clock();
133 #endif
134 }
135
136
137
end_cs_clock(CS_CLOCK * c,int count)138 void end_cs_clock(CS_CLOCK *c, int count)
139 {
140 CS_TIME curr;
141 if (c == NULL) return;
142 #ifdef _WIN32
143 {
144 FILETIME dummy, kernelCPU, userCPU;
145 GetThreadTimes(GetCurrentThread(), &dummy, &dummy, &kernelCPU,
146 &userCPU);
147 curr = kernelCPU.dwLowDateTime + ((__int64)kernelCPU.dwHighDateTime << 32) +
148 userCPU.dwLowDateTime + ((__int64)userCPU.dwHighDateTime << 32);
149 }
150 #elif defined(__vxworks)
151 curr = tickGet();
152 #else
153 curr = clock();
154 if (curr == -1) return; /* clock overrun */
155 #endif
156 c->total_time += curr - c->last;
157 c->last = curr;
158 c->ncalls ++;
159 c->item_count += count;
160 }
161
162
reset_cs_clock(CS_CLOCK * c)163 void reset_cs_clock(CS_CLOCK *c)
164 {
165 if (c == NULL) return;
166 c->ncalls = 0;
167 c->total_time = 0;
168 c->last = 0;
169 c->item_count = 0;
170 }
171
init_cs_clock(CS_CLOCK * c)172 void init_cs_clock(CS_CLOCK *c)
173 {
174 if (c == NULL) return;
175 #if _WIN32
176 c->clocks_per_msec = 10000.0;
177 #else
178 c->clocks_per_msec = (double) CLOCKS_PER_SEC / 1000.0;
179 #endif
180 reset_cs_clock(c);
181 }
182
183
make_cs_clock(void)184 CS_CLOCK *make_cs_clock(void)
185 {
186 CS_CLOCK *c = (CS_CLOCK *) NEW(CS_CLOCK, L("crec.cs_clock"));
187 init_cs_clock(c);
188 return c;
189 }
190