SphinxBase 0.6
profile.c
1/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/* ====================================================================
3 * Copyright (c) 1999-2001 Carnegie Mellon University. All rights
4 * reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * This work was supported in part by funding from the Defense Advanced
19 * Research Projects Agency and the National Science Foundation of the
20 * United States of America, and the CMU Sphinx Speech Consortium.
21 *
22 * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
23 * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
24 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
26 * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 * ====================================================================
35 *
36 */
37/*
38 * profile.c -- For timing and event counting.
39 *
40 * **********************************************
41 * CMU ARPA Speech Project
42 *
43 * Copyright (c) 1999 Carnegie Mellon University.
44 * ALL RIGHTS RESERVED.
45 * **********************************************
46 *
47 * HISTORY
48 * $Log: profile.c,v $
49 * Revision 1.7 2005/06/22 03:10:59 arthchan2003
50 * 1, Fixed doxygen documentation, 2, Added keyword.
51 *
52 * Revision 1.3 2005/03/30 01:22:48 archan
53 * Fixed mistakes in last updates. Add
54 *
55 *
56 * 11-Mar-1999 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
57 * Added ptmr_init().
58 *
59 * 19-Jun-97 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
60 * Created.
61 */
62
63#include <config.h>
64
65#include <stdio.h>
66#include <stdlib.h>
67#include <string.h>
68
69#if defined(_WIN32) && !defined(__SYMBIAN32__)
70# include <windows.h>
71# ifndef _WIN32_WCE
72# include <time.h>
73# endif
74#elif defined(HAVE_UNISTD_H) /* I know this, this is Unix... */
75# include <unistd.h>
76# include <sys/time.h>
77# include <sys/resource.h>
78#endif
79
80#ifdef _MSC_VER
81#pragma warning (disable: 4996)
82#endif
83
84#include "sphinxbase/profile.h"
85#include "sphinxbase/err.h"
87
88/* Silvio Moioli: updated to use Unicode */
89#ifdef _WIN32_WCE
90DWORD unlink(const char *filename)
91{
92 WCHAR *wfilename;
93 DWORD rv;
94 size_t len;
95
96 len = mbstowcs(NULL, filename, 0);
97 wfilename = ckd_calloc(len+1, sizeof(*wfilename));
98 mbstowcs(wfilename, filename, len);
99 rv = DeleteFileW(wfilename);
100 ckd_free(wfilename);
101
102 return rv;
103}
104#endif
105
106pctr_t *
107pctr_new(char *nm)
108{
109 pctr_t *pc;
110
111 pc = ckd_calloc(1, sizeof(pctr_t));
112 pc->name = ckd_salloc(nm);
113 pc->count = 0;
114
115 return pc;
116}
117
118void
120{
121 ctr->count = 0;
122}
123
124
125void
126pctr_increment(pctr_t * ctr, int32 inc)
127{
128 ctr->count += inc;
129 /* E_INFO("Name %s, Count %d, inc %d\n",ctr->name, ctr->count, inc); */
130}
131
132void
133pctr_print(FILE * fp, pctr_t * ctr)
134{
135 fprintf(fp, "CTR:");
136 fprintf(fp, "[%d %s]", ctr->count, ctr->name);
137}
138
139void
141{
142 if (pc) {
143 if (pc->name)
144 ckd_free(pc->name);
145 }
146 ckd_free(pc);
147}
148
149
150#if defined(_WIN32) && !defined(GNUWINCE) && !defined(__SYMBIAN32__)
151
152#define TM_LOWSCALE 1e-7
153#define TM_HIGHSCALE (4294967296.0 * TM_LOWSCALE);
154
155static float64
156make_sec(FILETIME * tm)
157{
158 float64 dt;
159
160 dt = tm->dwLowDateTime * TM_LOWSCALE;
161 dt += tm->dwHighDateTime * TM_HIGHSCALE;
162
163 return (dt);
164}
165
166#else /* NOT WINDOWS */
167
168static float64
169make_sec(struct timeval *s)
170{
171 return (s->tv_sec + s->tv_usec * 0.000001);
172}
173
174#endif
175
176
177void
179{
180#if (! defined(_WIN32)) || defined(GNUWINCE) || defined(__SYMBIAN32__)
181 struct timeval e_start; /* Elapsed time */
182
183#if (! defined(_HPUX_SOURCE)) && (! defined(__SYMBIAN32__))
184 struct rusage start; /* CPU time */
185
186 /* Unix but not HPUX */
187 getrusage(RUSAGE_SELF, &start);
188 tm->start_cpu = make_sec(&start.ru_utime) + make_sec(&start.ru_stime);
189#endif
190 /* Unix + HP */
191 gettimeofday(&e_start, 0);
192 tm->start_elapsed = make_sec(&e_start);
193#elif defined(_WIN32_WCE)
194 /* No GetProcessTimes() on WinCE. (Note CPU time will be bogus) */
195 tm->start_cpu = GetTickCount() / 1000;
196 tm->start_elapsed = GetTickCount() / 1000;
197#else
198 HANDLE pid;
199 FILETIME t_create, t_exit, kst, ust;
200
201 /* PC */
202 pid = GetCurrentProcess();
203 GetProcessTimes(pid, &t_create, &t_exit, &kst, &ust);
204 tm->start_cpu = make_sec(&ust) + make_sec(&kst);
205
206 tm->start_elapsed = (float64) clock() / CLOCKS_PER_SEC;
207#endif
208}
209
210
211void
213{
214 float64 dt_cpu, dt_elapsed;
215
216#if (! defined(_WIN32)) || defined(GNUWINCE) || defined(__SYMBIAN32__)
217 struct timeval e_stop; /* Elapsed time */
218
219#if (! defined(_HPUX_SOURCE)) && (! defined(__SYMBIAN32__))
220 struct rusage stop; /* CPU time */
221
222 /* Unix but not HPUX */
223 getrusage(RUSAGE_SELF, &stop);
224 dt_cpu =
225 make_sec(&stop.ru_utime) + make_sec(&stop.ru_stime) -
226 tm->start_cpu;
227#else
228 dt_cpu = 0.0;
229#endif
230 /* Unix + HP */
231 gettimeofday(&e_stop, 0);
232 dt_elapsed = (make_sec(&e_stop) - tm->start_elapsed);
233#elif defined(_WIN32_WCE)
234 /* No GetProcessTimes() on WinCE. (Note CPU time will be bogus) */
235 dt_cpu = GetTickCount() / 1000 - tm->start_cpu;
236 dt_elapsed = GetTickCount() / 1000 - tm->start_elapsed;
237#else
238 HANDLE pid;
239 FILETIME t_create, t_exit, kst, ust;
240
241 /* PC */
242 pid = GetCurrentProcess();
243 GetProcessTimes(pid, &t_create, &t_exit, &kst, &ust);
244 dt_cpu = make_sec(&ust) + make_sec(&kst) - tm->start_cpu;
245 dt_elapsed = ((float64) clock() / CLOCKS_PER_SEC) - tm->start_elapsed;
246#endif
247
248 tm->t_cpu += dt_cpu;
249 tm->t_elapsed += dt_elapsed;
250
251 tm->t_tot_cpu += dt_cpu;
252 tm->t_tot_elapsed += dt_elapsed;
253}
254
255
256void
258{
259 tm->t_cpu = 0.0;
260 tm->t_elapsed = 0.0;
261}
262
263
264void
266{
267 tm->t_cpu = 0.0;
268 tm->t_elapsed = 0.0;
269 tm->t_tot_cpu = 0.0;
270 tm->t_tot_elapsed = 0.0;
271}
272
273
274void
276{
277 for (; tm->name; tm++)
278 ptmr_reset(tm);
279}
280
281
282void
283ptmr_print_all(FILE * fp, ptmr_t * tm, float64 norm)
284{
285 if (norm != 0.0) {
286 norm = 1.0 / norm;
287 for (; tm->name; tm++)
288 fprintf(fp, " %6.2fx %s", tm->t_cpu * norm, tm->name);
289 }
290}
291
292
293int32
294host_endian(void)
295{
296 FILE *fp;
297 int32 BYTE_ORDER_MAGIC;
298 char *file;
299 char buf[8];
300 int32 k, endian;
301
302 file = "/tmp/__EnDiAn_TeSt__";
303
304 if ((fp = fopen(file, "wb")) == NULL) {
305 E_ERROR("Failed to open file '%s' for writing", file);
306 return -1;
307 }
308
309 BYTE_ORDER_MAGIC = (int32) 0x11223344;
310
311 k = (int32) BYTE_ORDER_MAGIC;
312 if (fwrite(&k, sizeof(int32), 1, fp) != 1) {
313 E_ERROR("Failed to write to file '%s'\n", file);
314 fclose(fp);
315 unlink(file);
316 return -1;
317 }
318
319 fclose(fp);
320 if ((fp = fopen(file, "rb")) == NULL) {
321 E_ERROR_SYSTEM("Failed to open file '%s' for reading", file);
322 unlink(file);
323 return -1;
324 }
325 if (fread(buf, 1, sizeof(int32), fp) != sizeof(int32)) {
326 E_ERROR("Failed to read from file '%s'\n", file);
327 fclose(fp);
328 unlink(file);
329 return -1;
330 }
331 fclose(fp);
332 unlink(file);
333
334 /* If buf[0] == lsB of BYTE_ORDER_MAGIC, we are little-endian */
335 endian = (buf[0] == (BYTE_ORDER_MAGIC & 0x000000ff)) ? 1 : 0;
336
337 return (endian);
338}
Sphinx's memory allocation/deallocation routines.
SPHINXBASE_EXPORT void ckd_free(void *ptr)
Test and free a 1-D array.
Definition ckd_alloc.c:241
#define ckd_calloc(n, sz)
Macros to simplify the use of above functions.
Definition ckd_alloc.h:248
#define ckd_salloc(ptr)
Macro for ckd_salloc
Definition ckd_alloc.h:264
Implementation of logging routines.
#define E_ERROR_SYSTEM
Print error text; Call perror("");.
Definition err.h:142
#define E_ERROR
Print error message to standard error stream.
Definition err.h:169
Implementation of profiling, include counting , timing, cpu clock checking.
SPHINXBASE_EXPORT void ptmr_print_all(FILE *fp, ptmr_t *tmr, float64 norm)
Print t_cpu for all timer modules in tmr[], normalized by norm (i.e., t_cpu/norm).
Definition profile.c:283
SPHINXBASE_EXPORT void ptmr_reset_all(ptmr_t *tmr)
Reset t_cpu, t_elapsed of all timer modules in array tmr[] to 0.0.
Definition profile.c:275
SPHINXBASE_EXPORT void pctr_increment(pctr_t *ctr, int32 inc)
Increment a counter.
Definition profile.c:126
SPHINXBASE_EXPORT void ptmr_reset(ptmr_t *tmr)
Reset tmr->{t_cpu, t_elapsed} to 0.0.
Definition profile.c:257
SPHINXBASE_EXPORT void pctr_print(FILE *fp, pctr_t *ctr)
Print a counter.
Definition profile.c:133
SPHINXBASE_EXPORT void ptmr_init(ptmr_t *tmr)
Reset tmr->{t_cpu, t_elapsed, t_tot_cpu, t_tot_elapsed} to 0.0.
Definition profile.c:265
SPHINXBASE_EXPORT pctr_t * pctr_new(char *name)
operations of pctr_t
Definition profile.c:107
SPHINXBASE_EXPORT void pctr_reset(pctr_t *ctr)
Reset a counter.
Definition profile.c:119
SPHINXBASE_EXPORT void pctr_free(pctr_t *ctr)
Free the counter.
Definition profile.c:140
SPHINXBASE_EXPORT void ptmr_start(ptmr_t *tmr)
Start timing using tmr.
Definition profile.c:178
SPHINXBASE_EXPORT void ptmr_stop(ptmr_t *tmr)
Stop timing and accumulate tmr->{t_cpu, t_elapsed, t_tot_cpu, t_tot_elapsed}.
Definition profile.c:212
Generic event counter for profiling.
Definition profile.h:100
char * name
Counter print name; NULL terminates array of counters Used by pctr_print_all.
Definition profile.h:101
int32 count
Counter value.
Definition profile.h:104
Generic timer structures and functions for coarse-grained performance measurements using standard sys...
Definition profile.h:157
float64 start_elapsed
-— FOR INTERNAL USE ONLY -—
Definition profile.h:165
float64 t_tot_elapsed
Total elapsed time since creation.
Definition profile.h:163
float64 t_tot_cpu
Total CPU time since creation.
Definition profile.h:162
const char * name
Timer print name; NULL terminates an array of timers.
Definition profile.h:158
float64 t_elapsed
Elapsed time accumulated since most recent reset.
Definition profile.h:161
float64 start_cpu
-— FOR INTERNAL USE ONLY -—
Definition profile.h:164
float64 t_cpu
CPU time accumulated since most recent reset op.
Definition profile.h:160