SphinxBase 5prealpha
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#ifdef HAVE_CONFIG_H
64#include <config.h>
65#endif
66
67#include <stdio.h>
68#include <stdlib.h>
69#include <string.h>
70
71#if defined(_WIN32) && !defined(__SYMBIAN32__)
72# include <windows.h>
73# ifndef _WIN32_WCE
74# include <time.h>
75# endif
76#elif defined(HAVE_UNISTD_H) /* I know this, this is Unix... */
77# include <unistd.h>
78# include <sys/time.h>
79# include <sys/resource.h>
80#endif
81
82#ifdef _MSC_VER
83#pragma warning (disable: 4996)
84#endif
85
86#include "sphinxbase/profile.h"
87#include "sphinxbase/err.h"
89
90#if defined(_WIN32_WCE) || defined(_WIN32_WP)
91DWORD unlink(const char *filename)
92{
93 WCHAR *wfilename;
94 DWORD rv;
95 size_t len;
96
97 len = mbstowcs(NULL, filename, 0);
98 wfilename = ckd_calloc(len+1, sizeof(*wfilename));
99 mbstowcs(wfilename, filename, len);
100 rv = DeleteFileW(wfilename);
101 ckd_free(wfilename);
102
103 return rv;
104}
105#endif
106
107pctr_t *
108pctr_new(char *nm)
109{
110 pctr_t *pc;
111
112 pc = ckd_calloc(1, sizeof(pctr_t));
113 pc->name = ckd_salloc(nm);
114 pc->count = 0;
115
116 return pc;
117}
118
119void
121{
122 ctr->count = 0;
123}
124
125
126void
127pctr_increment(pctr_t * ctr, int32 inc)
128{
129 ctr->count += inc;
130 /* E_INFO("Name %s, Count %d, inc %d\n",ctr->name, ctr->count, inc); */
131}
132
133void
134pctr_print(FILE * fp, pctr_t * ctr)
135{
136 fprintf(fp, "CTR:");
137 fprintf(fp, "[%d %s]", ctr->count, ctr->name);
138}
139
140void
142{
143 if (pc) {
144 if (pc->name)
145 ckd_free(pc->name);
146 }
147 ckd_free(pc);
148}
149
150
151#if defined(_WIN32) && !defined(GNUWINCE) && !defined(__SYMBIAN32__)
152
153#define TM_LOWSCALE 1e-7
154#define TM_HIGHSCALE (4294967296.0 * TM_LOWSCALE);
155
156static float64
157make_sec(FILETIME * tm)
158{
159 float64 dt;
160
161 dt = tm->dwLowDateTime * TM_LOWSCALE;
162 dt += tm->dwHighDateTime * TM_HIGHSCALE;
163
164 return (dt);
165}
166
167#else /* NOT WINDOWS */
168
169static float64
170make_sec(struct timeval *s)
171{
172 return (s->tv_sec + s->tv_usec * 0.000001);
173}
174
175#endif
176
177
178void
180{
181#if (! defined(_WIN32)) || defined(GNUWINCE) || defined(__SYMBIAN32__)
182 struct timeval e_start; /* Elapsed time */
183
184#if (! defined(_HPUX_SOURCE)) && (! defined(__SYMBIAN32__))
185 struct rusage start; /* CPU time */
186
187 /* Unix but not HPUX */
188 getrusage(RUSAGE_SELF, &start);
189 tm->start_cpu = make_sec(&start.ru_utime) + make_sec(&start.ru_stime);
190#endif
191 /* Unix + HP */
192 gettimeofday(&e_start, 0);
193 tm->start_elapsed = make_sec(&e_start);
194#elif defined(_WIN32_WP)
195 tm->start_cpu = GetTickCount64() / 1000;
196 tm->start_elapsed = GetTickCount64() / 1000;
197#elif defined(_WIN32_WCE)
198 /* No GetProcessTimes() on WinCE. (Note CPU time will be bogus) */
199 tm->start_cpu = GetTickCount() / 1000;
200 tm->start_elapsed = GetTickCount() / 1000;
201#else
202 HANDLE pid;
203 FILETIME t_create, t_exit, kst, ust;
204
205 /* PC */
206 pid = GetCurrentProcess();
207 GetProcessTimes(pid, &t_create, &t_exit, &kst, &ust);
208 tm->start_cpu = make_sec(&ust) + make_sec(&kst);
209
210 tm->start_elapsed = (float64) clock() / CLOCKS_PER_SEC;
211#endif
212}
213
214
215void
217{
218 float64 dt_cpu, dt_elapsed;
219
220#if (! defined(_WIN32)) || defined(GNUWINCE) || defined(__SYMBIAN32__)
221 struct timeval e_stop; /* Elapsed time */
222
223#if (! defined(_HPUX_SOURCE)) && (! defined(__SYMBIAN32__))
224 struct rusage stop; /* CPU time */
225
226 /* Unix but not HPUX */
227 getrusage(RUSAGE_SELF, &stop);
228 dt_cpu =
229 make_sec(&stop.ru_utime) + make_sec(&stop.ru_stime) -
230 tm->start_cpu;
231#else
232 dt_cpu = 0.0;
233#endif
234 /* Unix + HP */
235 gettimeofday(&e_stop, 0);
236 dt_elapsed = (make_sec(&e_stop) - tm->start_elapsed);
237#elif defined(_WIN32_WP)
238 dt_cpu = GetTickCount64() / 1000 - tm->start_cpu;
239 dt_elapsed = GetTickCount64() / 1000 - tm->start_elapsed;
240#elif defined(_WIN32_WCE)
241 /* No GetProcessTimes() on WinCE. (Note CPU time will be bogus) */
242 dt_cpu = GetTickCount() / 1000 - tm->start_cpu;
243 dt_elapsed = GetTickCount() / 1000 - tm->start_elapsed;
244#else
245 HANDLE pid;
246 FILETIME t_create, t_exit, kst, ust;
247
248 /* PC */
249 pid = GetCurrentProcess();
250 GetProcessTimes(pid, &t_create, &t_exit, &kst, &ust);
251 dt_cpu = make_sec(&ust) + make_sec(&kst) - tm->start_cpu;
252 dt_elapsed = ((float64) clock() / CLOCKS_PER_SEC) - tm->start_elapsed;
253#endif
254
255 tm->t_cpu += dt_cpu;
256 tm->t_elapsed += dt_elapsed;
257
258 tm->t_tot_cpu += dt_cpu;
259 tm->t_tot_elapsed += dt_elapsed;
260}
261
262
263void
265{
266 tm->t_cpu = 0.0;
267 tm->t_elapsed = 0.0;
268}
269
270
271void
273{
274 tm->t_cpu = 0.0;
275 tm->t_elapsed = 0.0;
276 tm->t_tot_cpu = 0.0;
277 tm->t_tot_elapsed = 0.0;
278}
279
280
281void
283{
284 for (; tm->name; tm++)
285 ptmr_reset(tm);
286}
287
288
289void
290ptmr_print_all(FILE * fp, ptmr_t * tm, float64 norm)
291{
292 if (norm != 0.0) {
293 norm = 1.0 / norm;
294 for (; tm->name; tm++)
295 fprintf(fp, " %6.2fx %s", tm->t_cpu * norm, tm->name);
296 }
297}
298
299
300int32
301host_endian(void)
302{
303 FILE *fp;
304 int32 BYTE_ORDER_MAGIC;
305 char *file;
306 char buf[8];
307 int32 k, endian;
308
309 file = "/tmp/__EnDiAn_TeSt__";
310
311 if ((fp = fopen(file, "wb")) == NULL) {
312 E_ERROR("Failed to open file '%s' for writing", file);
313 return -1;
314 }
315
316 BYTE_ORDER_MAGIC = (int32) 0x11223344;
317
318 k = (int32) BYTE_ORDER_MAGIC;
319 if (fwrite(&k, sizeof(int32), 1, fp) != 1) {
320 E_ERROR("Failed to write to file '%s'\n", file);
321 fclose(fp);
322 unlink(file);
323 return -1;
324 }
325
326 fclose(fp);
327 if ((fp = fopen(file, "rb")) == NULL) {
328 E_ERROR_SYSTEM("Failed to open file '%s' for reading", file);
329 unlink(file);
330 return -1;
331 }
332 if (fread(buf, 1, sizeof(int32), fp) != sizeof(int32)) {
333 E_ERROR("Failed to read from file '%s'\n", file);
334 fclose(fp);
335 unlink(file);
336 return -1;
337 }
338 fclose(fp);
339 unlink(file);
340
341 /* If buf[0] == lsB of BYTE_ORDER_MAGIC, we are little-endian */
342 endian = (buf[0] == (BYTE_ORDER_MAGIC & 0x000000ff)) ? 1 : 0;
343
344 return (endian);
345}
Sphinx's memory allocation/deallocation routines.
SPHINXBASE_EXPORT void ckd_free(void *ptr)
Test and free a 1-D array.
Definition ckd_alloc.c:244
#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(...)
Print error message to error log.
Definition err.h:104
#define E_ERROR_SYSTEM(...)
Print error text; Call perror("");.
Definition err.h:99
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:290
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:282
SPHINXBASE_EXPORT void pctr_increment(pctr_t *ctr, int32 inc)
Increment a counter.
Definition profile.c:127
SPHINXBASE_EXPORT void ptmr_reset(ptmr_t *tmr)
Reset tmr->{t_cpu, t_elapsed} to 0.0.
Definition profile.c:264
SPHINXBASE_EXPORT void pctr_print(FILE *fp, pctr_t *ctr)
Print a counter.
Definition profile.c:134
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:272
SPHINXBASE_EXPORT pctr_t * pctr_new(char *name)
operations of pctr_t
Definition profile.c:108
SPHINXBASE_EXPORT void pctr_reset(pctr_t *ctr)
Reset a counter.
Definition profile.c:120
SPHINXBASE_EXPORT void pctr_free(pctr_t *ctr)
Free the counter.
Definition profile.c:141
SPHINXBASE_EXPORT void ptmr_start(ptmr_t *tmr)
Start timing using tmr.
Definition profile.c:179
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:216
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