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"
88 #include "sphinxbase/ckd_alloc.h"
89 
90 #if defined(_WIN32_WCE) || defined(_WIN32_WP)
91 DWORD 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 
107 pctr_t *
108 pctr_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 
119 void
121 {
122  ctr->count = 0;
123 }
124 
125 
126 void
127 pctr_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 
133 void
134 pctr_print(FILE * fp, pctr_t * ctr)
135 {
136  fprintf(fp, "CTR:");
137  fprintf(fp, "[%d %s]", ctr->count, ctr->name);
138 }
139 
140 void
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 
156 static float64
157 make_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 
169 static float64
170 make_sec(struct timeval *s)
171 {
172  return (s->tv_sec + s->tv_usec * 0.000001);
173 }
174 
175 #endif
176 
177 
178 void
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 
215 void
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 
263 void
265 {
266  tm->t_cpu = 0.0;
267  tm->t_elapsed = 0.0;
268 }
269 
270 
271 void
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 
281 void
283 {
284  for (; tm->name; tm++)
285  ptmr_reset(tm);
286 }
287 
288 
289 void
290 ptmr_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 
300 int32
301 host_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 }
#define E_ERROR_SYSTEM(...)
Print error text; Call perror(&quot;&quot;);.
Definition: err.h:99
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 pctr_t * pctr_new(char *name)
operations of pctr_t
Definition: profile.c:108
int32 count
Counter value.
Definition: profile.h:104
#define ckd_calloc(n, sz)
Macros to simplify the use of above functions.
Definition: ckd_alloc.h:248
SPHINXBASE_EXPORT void ptmr_start(ptmr_t *tmr)
Start timing using tmr.
Definition: profile.c:179
#define E_ERROR(...)
Print error message to error log.
Definition: err.h:104
Sphinx&#39;s memory allocation/deallocation routines.
float64 t_tot_elapsed
Total elapsed time since creation.
Definition: profile.h:163
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
#define ckd_salloc(ptr)
Macro for ckd_salloc
Definition: ckd_alloc.h:264
float64 start_cpu
-— FOR INTERNAL USE ONLY -—
Definition: profile.h:164
const char * name
Timer print name; NULL terminates an array of timers.
Definition: profile.h:158
SPHINXBASE_EXPORT void ckd_free(void *ptr)
Test and free a 1-D array.
Definition: ckd_alloc.c:244
SPHINXBASE_EXPORT void pctr_free(pctr_t *ctr)
Free the counter.
Definition: profile.c:141
SPHINXBASE_EXPORT void pctr_print(FILE *fp, pctr_t *ctr)
Print a counter.
Definition: profile.c:134
float64 t_cpu
CPU time accumulated since most recent reset op.
Definition: profile.h:160
float64 t_tot_cpu
Total CPU time since creation.
Definition: profile.h:162
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 pctr_increment(pctr_t *ctr, int32 inc)
Increment a counter.
Definition: profile.c:127
SPHINXBASE_EXPORT void pctr_reset(pctr_t *ctr)
Reset a counter.
Definition: profile.c:120
SPHINXBASE_EXPORT void ptmr_init(ptmr_t *tmr)
Reset tmr-&gt;{t_cpu, t_elapsed, t_tot_cpu, t_tot_elapsed} to 0.0.
Definition: profile.c:272
Implementation of logging routines.
SPHINXBASE_EXPORT void ptmr_stop(ptmr_t *tmr)
Stop timing and accumulate tmr-&gt;{t_cpu, t_elapsed, t_tot_cpu, t_tot_elapsed}.
Definition: profile.c:216
float64 t_elapsed
Elapsed time accumulated since most recent reset.
Definition: profile.h:161
Implementation of profiling, include counting , timing, cpu clock checking.
SPHINXBASE_EXPORT void ptmr_reset(ptmr_t *tmr)
Reset tmr-&gt;{t_cpu, t_elapsed} to 0.0.
Definition: profile.c:264
char * name
Counter print name; NULL terminates array of counters Used by pctr_print_all.
Definition: profile.h:101
Generic event counter for profiling.
Definition: profile.h:100