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"
86 #include "sphinxbase/ckd_alloc.h"
87 
88 /* Silvio Moioli: updated to use Unicode */
89 #ifdef _WIN32_WCE
90 DWORD 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 
106 pctr_t *
107 pctr_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 
118 void
120 {
121  ctr->count = 0;
122 }
123 
124 
125 void
126 pctr_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 
132 void
133 pctr_print(FILE * fp, pctr_t * ctr)
134 {
135  fprintf(fp, "CTR:");
136  fprintf(fp, "[%d %s]", ctr->count, ctr->name);
137 }
138 
139 void
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 
155 static float64
156 make_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 
168 static float64
169 make_sec(struct timeval *s)
170 {
171  return (s->tv_sec + s->tv_usec * 0.000001);
172 }
173 
174 #endif
175 
176 
177 void
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 
211 void
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 
256 void
258 {
259  tm->t_cpu = 0.0;
260  tm->t_elapsed = 0.0;
261 }
262 
263 
264 void
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 
274 void
276 {
277  for (; tm->name; tm++)
278  ptmr_reset(tm);
279 }
280 
281 
282 void
283 ptmr_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 
293 int32
294 host_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 }
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 pctr_t * pctr_new(char *name)
operations of pctr_t
Definition: profile.c:107
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:178
Sphinx'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:241
SPHINXBASE_EXPORT void pctr_free(pctr_t *ctr)
Free the counter.
Definition: profile.c:140
SPHINXBASE_EXPORT void pctr_print(FILE *fp, pctr_t *ctr)
Print a counter.
Definition: profile.c:133
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:283
SPHINXBASE_EXPORT void pctr_increment(pctr_t *ctr, int32 inc)
Increment a counter.
Definition: profile.c:126
SPHINXBASE_EXPORT void pctr_reset(pctr_t *ctr)
Reset a counter.
Definition: profile.c:119
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
Implementation of logging routines.
#define E_ERROR
Print error message to standard error stream.
Definition: err.h:169
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
float64 t_elapsed
Elapsed time accumulated since most recent reset.
Definition: profile.h:161
Implementation of profiling, include counting , timing, cpu clock checking.
#define E_ERROR_SYSTEM
Print error text; Call perror("");.
Definition: err.h:142
SPHINXBASE_EXPORT void ptmr_reset(ptmr_t *tmr)
Reset tmr->{t_cpu, t_elapsed} to 0.0.
Definition: profile.c:257
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