blob: aacbac69602146a8a34ffbb31ac45c6a2484f6bf [file] [log] [blame]
/*---------------------------------------------------------------------------*
* comp_stats.c *
* *
* Copyright 2007, 2008 Nuance Communciations, Inc. *
* *
* Licensed under the Apache License, Version 2.0 (the 'License'); *
* you may not use this file except in compliance with the License. *
* *
* You may obtain a copy of the License at *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an 'AS IS' BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
* *
*---------------------------------------------------------------------------*/
#include "buildopt.h"
#include "pstdio.h"
#include "passert.h"
#include <time.h>
#include "comp_stats.h"
#include "portable.h"
#include "PFile.h"
#ifdef SET_RCSID
static const char *rcsid = 0 ? (const char *) &rcsid : "$Id: compstats now";
#endif
#if defined(__cplusplus)
extern "C"
{
#endif
COMP_STATS *comp_stats = NULL;
#if defined(__cplusplus)
}
#endif
/* create COMP_STATS object */
COMP_STATS *init_comp_stats(void)
{
static COMP_STATS c;
/*c = (COMP_STATS *) calloc( 1, sizeof( COMP_STATS ));*/
/*c = (COMP_STATS *) NEW( COMP_STATS, L("crec.comp_stats")); */
init_cs_clock(&c.overall_search);
init_cs_clock(&c.models);
init_cs_clock(&c.fsm_to_hmm);
init_cs_clock(&c.internal_hmm);
init_cs_clock(&c.hmm_to_fsm);
init_cs_clock(&c.epsilon);
init_cs_clock(&c.astar);
init_cs_clock(&c.prune);
init_cs_clock(&c.front_end);
init_cs_clock(&c.word_lookup);
init_cs_clock(&c.word_addition);
c.total_time = 0;
return &c;
}
void dump_comp_stats(COMP_STATS *cs, PFile* fp)
{
if (getenv("HIDE_COMP_STATS"))
return;
#if !defined(_WIN32) && !defined(__vxworks)
if (clock() == (clock_t) - 1)
{
pfprintf(fp, "***WARNING: clock overrun!\n");
}
#endif
if (!cs) cs = comp_stats;
#ifdef SREC_ENGINE_VERBOSE_LOGGING
pfprintf(fp, "Total Time %5.2f Seconds\n", cs->total_time);
#endif
print_cs_clock(&cs->front_end, cs->total_time, fp, "Front end", "Frames");
print_cs_clock(&cs->overall_search, cs->total_time, fp, "Total Search", "Frames");
print_cs_clock(&cs->models, cs->total_time, fp, " Models", "Models");
print_cs_clock(&cs->internal_hmm, cs->total_time, fp, " Internal HMM", "HMMs");
print_cs_clock(&cs->fsm_to_hmm, cs->total_time, fp, " FSM to HMM", "FSM_Nodes");
print_cs_clock(&cs->prune, cs->total_time, fp, " Prune", "HMM States");
print_cs_clock(&cs->hmm_to_fsm, cs->total_time, fp, " HMM to FSM", "HMMS");
print_cs_clock(&cs->epsilon, cs->total_time, fp, " Epsilon", "FSM_Nodes");
print_cs_clock(&cs->astar, cs->total_time, fp, " Astar", "Utterances");
print_cs_clock(&cs->word_lookup, cs->total_time, fp, " WordLookup", "Words");
print_cs_clock(&cs->word_addition, cs->total_time, fp, " WordAdd'tn", "Pronunciations");
pfflush(fp);
}
void print_cs_clock(CS_CLOCK *c, float num_seconds, PFile* fp, char *prompt, char *item_name)
{
if (c == NULL) return;
/* FPRINTF( fp, "%15.15s %8.2f. Per Second of speech: %6.2f ms, %6.2f calls, %6.2f (%d) %s\n",
prompt ? prompt : "",
c->total_time/c->clocks_per_msec,
(c->total_time/c->clocks_per_msec) / num_seconds,
c->ncalls / num_seconds,
c->item_count / num_seconds,
c->item_count,
item_name);*/
}
void start_cs_clock(CS_CLOCK *c)
{
if (c == NULL) return;
#ifdef _WIN32
{
FILETIME dummy, kernelCPU, userCPU;
GetThreadTimes(GetCurrentThread(), &dummy, &dummy, &kernelCPU,
&userCPU);
c->last = kernelCPU.dwLowDateTime + ((__int64)kernelCPU.dwHighDateTime << 32) +
userCPU.dwLowDateTime + ((__int64)userCPU.dwHighDateTime << 32);
}
#elif defined(__vxworks)
/* Should use a portable clock() */
/* WxWorks: clock() always returns -1. VxWorks does not track per-task time or system idle time.
There is no method of determining how long a task or the entire system has been doing work.
tickGet( ) can be used to query the number of system ticks since system start.
clock_gettime( ) can be used to get the current clock time.
*/
c->last = tickGet();
#else
c->last = clock();
#endif
}
void end_cs_clock(CS_CLOCK *c, int count)
{
CS_TIME curr;
if (c == NULL) return;
#ifdef _WIN32
{
FILETIME dummy, kernelCPU, userCPU;
GetThreadTimes(GetCurrentThread(), &dummy, &dummy, &kernelCPU,
&userCPU);
curr = kernelCPU.dwLowDateTime + ((__int64)kernelCPU.dwHighDateTime << 32) +
userCPU.dwLowDateTime + ((__int64)userCPU.dwHighDateTime << 32);
}
#elif defined(__vxworks)
curr = tickGet();
#else
curr = clock();
if (curr == -1) return; /* clock overrun */
#endif
c->total_time += curr - c->last;
c->last = curr;
c->ncalls ++;
c->item_count += count;
}
void reset_cs_clock(CS_CLOCK *c)
{
if (c == NULL) return;
c->ncalls = 0;
c->total_time = 0;
c->last = 0;
c->item_count = 0;
}
void init_cs_clock(CS_CLOCK *c)
{
if (c == NULL) return;
#if _WIN32
c->clocks_per_msec = 10000.0;
#else
c->clocks_per_msec = (double) CLOCKS_PER_SEC / 1000.0;
#endif
reset_cs_clock(c);
}
CS_CLOCK *make_cs_clock(void)
{
CS_CLOCK *c = (CS_CLOCK *) NEW(CS_CLOCK, L("crec.cs_clock"));
init_cs_clock(c);
return c;
}