profile.c
/* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* ====================================================================
* Copyright (c) 1999-2001 Carnegie Mellon University. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* This work was supported in part by funding from the Defense Advanced
* Research Projects Agency and the National Science Foundation of the
* United States of America, and the CMU Sphinx Speech Consortium.
*
* THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
* ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
* NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ====================================================================
*
*/
/*
* profile.c -- For timing and event counting.
*
* **********************************************
* CMU ARPA Speech Project
*
* Copyright (c) 1999 Carnegie Mellon University.
* ALL RIGHTS RESERVED.
* **********************************************
*
* HISTORY
* $Log: profile.c,v $
* Revision 1.7 2005/06/22 03:10:59 arthchan2003
* 1, Fixed doxygen documentation, 2, Added keyword.
*
* Revision 1.3 2005/03/30 01:22:48 archan
* Fixed mistakes in last updates. Add
*
*
* 11-Mar-1999 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
* Added ptmr_init().
*
* 19-Jun-97 M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
* Created.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(_WIN32) && !defined(__SYMBIAN32__)
# include <windows.h>
# ifndef _WIN32_WCE
# include <time.h>
# endif
#elif defined(HAVE_UNISTD_H) /* I know this, this is Unix... */
# include <unistd.h>
# include <sys/time.h>
# include <sys/resource.h>
#endif
#ifdef _MSC_VER
#pragma warning (disable: 4996)
#endif
#include "sphinxbase/profile.h"
#include "sphinxbase/err.h"
#include "sphinxbase/ckd_alloc.h"
/* Silvio Moioli: updated to use Unicode */
#ifdef _WIN32_WCE
DWORD unlink(const char *filename)
{
WCHAR *wfilename;
DWORD rv;
size_t len;
len = mbstowcs(NULL, filename, 0);
wfilename = ckd_calloc(len+1, sizeof(*wfilename));
mbstowcs(wfilename, filename, len);
rv = DeleteFileW(wfilename);
ckd_free(wfilename);
return rv;
}
#endif
pctr_t *
pctr_new(char *nm)
{
pctr_t *pc;
pc = ckd_calloc(1, sizeof(pctr_t));
pc->name = ckd_salloc(nm);
pc->count = 0;
return pc;
}
void
pctr_reset(pctr_t * ctr)
{
ctr->count = 0;
}
void
pctr_increment(pctr_t * ctr, int32 inc)
{
ctr->count += inc;
/* E_INFO("Name %s, Count %d, inc %d\n",ctr->name, ctr->count, inc); */
}
void
pctr_print(FILE * fp, pctr_t * ctr)
{
fprintf(fp, "CTR:");
fprintf(fp, "[%d %s]", ctr->count, ctr->name);
}
void
pctr_free(pctr_t * pc)
{
if (pc) {
if (pc->name)
ckd_free(pc->name);
}
ckd_free(pc);
}
#if defined(_WIN32) && !defined(GNUWINCE) && !defined(__SYMBIAN32__)
#define TM_LOWSCALE 1e-7
#define TM_HIGHSCALE (4294967296.0 * TM_LOWSCALE);
static float64
make_sec(FILETIME * tm)
{
float64 dt;
dt = tm->dwLowDateTime * TM_LOWSCALE;
dt += tm->dwHighDateTime * TM_HIGHSCALE;
return (dt);
}
#else /* NOT WINDOWS */
static float64
make_sec(struct timeval *s)
{
return (s->tv_sec + s->tv_usec * 0.000001);
}
#endif
void
ptmr_start(ptmr_t * tm)
{
#if (! defined(_WIN32)) || defined(GNUWINCE) || defined(__SYMBIAN32__)
struct timeval e_start; /* Elapsed time */
#if (! defined(_HPUX_SOURCE)) && (! defined(__SYMBIAN32__))
struct rusage start; /* CPU time */
/* Unix but not HPUX */
getrusage(RUSAGE_SELF, &start);
tm->start_cpu = make_sec(&start.ru_utime) + make_sec(&start.ru_stime);
#endif
/* Unix + HP */
gettimeofday(&e_start, 0);
tm->start_elapsed = make_sec(&e_start);
#elif defined(_WIN32_WCE)
/* No GetProcessTimes() on WinCE. (Note CPU time will be bogus) */
tm->start_cpu = GetTickCount() / 1000;
tm->start_elapsed = GetTickCount() / 1000;
#else
HANDLE pid;
FILETIME t_create, t_exit, kst, ust;
/* PC */
pid = GetCurrentProcess();
GetProcessTimes(pid, &t_create, &t_exit, &kst, &ust);
tm->start_cpu = make_sec(&ust) + make_sec(&kst);
tm->start_elapsed = (float64) clock() / CLOCKS_PER_SEC;
#endif
}
void
ptmr_stop(ptmr_t * tm)
{
float64 dt_cpu, dt_elapsed;
#if (! defined(_WIN32)) || defined(GNUWINCE) || defined(__SYMBIAN32__)
struct timeval e_stop; /* Elapsed time */
#if (! defined(_HPUX_SOURCE)) && (! defined(__SYMBIAN32__))
struct rusage stop; /* CPU time */
/* Unix but not HPUX */
getrusage(RUSAGE_SELF, &stop);
dt_cpu =
make_sec(&stop.ru_utime) + make_sec(&stop.ru_stime) -
tm->start_cpu;
#else
dt_cpu = 0.0;
#endif
/* Unix + HP */
gettimeofday(&e_stop, 0);
dt_elapsed = (make_sec(&e_stop) - tm->start_elapsed);
#elif defined(_WIN32_WCE)
/* No GetProcessTimes() on WinCE. (Note CPU time will be bogus) */
dt_cpu = GetTickCount() / 1000 - tm->start_cpu;
dt_elapsed = GetTickCount() / 1000 - tm->start_elapsed;
#else
HANDLE pid;
FILETIME t_create, t_exit, kst, ust;
/* PC */
pid = GetCurrentProcess();
GetProcessTimes(pid, &t_create, &t_exit, &kst, &ust);
dt_cpu = make_sec(&ust) + make_sec(&kst) - tm->start_cpu;
dt_elapsed = ((float64) clock() / CLOCKS_PER_SEC) - tm->start_elapsed;
#endif
tm->t_cpu += dt_cpu;
tm->t_elapsed += dt_elapsed;
tm->t_tot_cpu += dt_cpu;
tm->t_tot_elapsed += dt_elapsed;
}
void
ptmr_reset(ptmr_t * tm)
{
tm->t_cpu = 0.0;
tm->t_elapsed = 0.0;
}
void
ptmr_init(ptmr_t * tm)
{
tm->t_cpu = 0.0;
tm->t_elapsed = 0.0;
tm->t_tot_cpu = 0.0;
tm->t_tot_elapsed = 0.0;
}
void
ptmr_reset_all(ptmr_t * tm)
{
for (; tm->name; tm++)
ptmr_reset(tm);
}
void
ptmr_print_all(FILE * fp, ptmr_t * tm, float64 norm)
{
if (norm != 0.0) {
norm = 1.0 / norm;
for (; tm->name; tm++)
fprintf(fp, " %6.2fx %s", tm->t_cpu * norm, tm->name);
}
}
int32
host_endian(void)
{
FILE *fp;
int32 BYTE_ORDER_MAGIC;
char *file;
char buf[8];
int32 k, endian;
file = "/tmp/__EnDiAn_TeSt__";
if ((fp = fopen(file, "wb")) == NULL) {
E_ERROR("Failed to open file '%s' for writing", file);
return -1;
}
BYTE_ORDER_MAGIC = (int32) 0x11223344;
k = (int32) BYTE_ORDER_MAGIC;
if (fwrite(&k, sizeof(int32), 1, fp) != 1) {
E_ERROR("Failed to write to file '%s'\n", file);
fclose(fp);
unlink(file);
return -1;
}
fclose(fp);
if ((fp = fopen(file, "rb")) == NULL) {
E_ERROR_SYSTEM("Failed to open file '%s' for reading", file);
unlink(file);
return -1;
}
if (fread(buf, 1, sizeof(int32), fp) != sizeof(int32)) {
E_ERROR("Failed to read from file '%s'\n", file);
fclose(fp);
unlink(file);
return -1;
}
fclose(fp);
unlink(file);
/* If buf[0] == lsB of BYTE_ORDER_MAGIC, we are little-endian */
endian = (buf[0] == (BYTE_ORDER_MAGIC & 0x000000ff)) ? 1 : 0;
return (endian);
}
ptmr_reset_all
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
pctr_new
SPHINXBASE_EXPORT pctr_t * pctr_new(char *name)
operations of pctr_t
Definition: profile.c:107
pctr_t::count
int32 count
Counter value.
Definition: profile.h:104
ckd_calloc
#define ckd_calloc(n, sz)
Macros to simplify the use of above functions.
Definition: ckd_alloc.h:248
ptmr_start
SPHINXBASE_EXPORT void ptmr_start(ptmr_t *tmr)
Start timing using tmr.
Definition: profile.c:178
ckd_alloc.h
Sphinx's memory allocation/deallocation routines.
ptmr_t::t_tot_elapsed
float64 t_tot_elapsed
Total elapsed time since creation.
Definition: profile.h:163
ptmr_t
Generic timer structures and functions for coarse-grained performance measurements using standard sys...
Definition: profile.h:157
ptmr_t::start_elapsed
float64 start_elapsed
-— FOR INTERNAL USE ONLY -—
Definition: profile.h:165
ckd_salloc
#define ckd_salloc(ptr)
Macro for ckd_salloc
Definition: ckd_alloc.h:264
ptmr_t::start_cpu
float64 start_cpu
-— FOR INTERNAL USE ONLY -—
Definition: profile.h:164
ptmr_t::name
const char * name
Timer print name; NULL terminates an array of timers.
Definition: profile.h:158
ckd_free
SPHINXBASE_EXPORT void ckd_free(void *ptr)
Test and free a 1-D array.
Definition: ckd_alloc.c:241
pctr_free
SPHINXBASE_EXPORT void pctr_free(pctr_t *ctr)
Free the counter.
Definition: profile.c:140
pctr_print
SPHINXBASE_EXPORT void pctr_print(FILE *fp, pctr_t *ctr)
Print a counter.
Definition: profile.c:133
ptmr_t::t_cpu
float64 t_cpu
CPU time accumulated since most recent reset op.
Definition: profile.h:160
ptmr_t::t_tot_cpu
float64 t_tot_cpu
Total CPU time since creation.
Definition: profile.h:162
ptmr_print_all
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
pctr_increment
SPHINXBASE_EXPORT void pctr_increment(pctr_t *ctr, int32 inc)
Increment a counter.
Definition: profile.c:126
pctr_reset
SPHINXBASE_EXPORT void pctr_reset(pctr_t *ctr)
Reset a counter.
Definition: profile.c:119
ptmr_init
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
err.h
Implementation of logging routines.
E_ERROR
#define E_ERROR
Print error message to standard error stream.
Definition: err.h:169
ptmr_stop
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
ptmr_t::t_elapsed
float64 t_elapsed
Elapsed time accumulated since most recent reset.
Definition: profile.h:161
profile.h
Implementation of profiling, include counting , timing, cpu clock checking.
E_ERROR_SYSTEM
#define E_ERROR_SYSTEM
Print error text; Call perror("");.
Definition: err.h:142
ptmr_reset
SPHINXBASE_EXPORT void ptmr_reset(ptmr_t *tmr)
Reset tmr->{t_cpu, t_elapsed} to 0.0.
Definition: profile.c:257
pctr_t::name
char * name
Counter print name; NULL terminates array of counters Used by pctr_print_all.
Definition: profile.h:101
pctr_t
Generic event counter for profiling.
Definition: profile.h:100