Skip to content

Instantly share code, notes, and snippets.

@bmnick
Created January 12, 2012 16:17
Show Gist options
  • Save bmnick/1601394 to your computer and use it in GitHub Desktop.
Save bmnick/1601394 to your computer and use it in GitHub Desktop.
/******************************************************************************
* Module (there is no .c file, only this header) to provide timing
* instrumentation macros. The timing instrumentation macros can be
* globally enabled and controlled as using the EN TIME macro. This macro
* can be defined or un-defined within a source code file (even within this
* file). If this is done then the timers cannot be controlled from the
* compiler command line. Since it will often be the case that the
* application would be built with and without the timers it is recommended
* that the EN TIME macro *not* be defined or un-defined directly in the
* source code. Instead, by using the “-D” command line option to gcc (as
* in “gcc -DEN TIME ...”) the timers can be enabled as needed. A compiler
* warning will be issued when the timers are enabled. All timer output is
* performed to stderr.
******************************************************************************/
#ifndef _TIMERS_H
#define _TIMERS_H
/******************************************************************************
* It is important that the user know that the timers are enabled when the
* code is compiled. The following pre-processor code issues a warning and
* includes the necessary system header files when the timers are enabled.
******************************************************************************/
#if defined(EN_TIME)
#include <stdio.h>
#include <time.h>
#if defined(WARNING_MSG)
#warning Timers enabled! Execution could be adversly effected.
#endif
#endif
/******************************************************************************
* The time instrumentation macro definitions. If EN TIME is *not* defined
* the macros are defined as null comments to allow the code to correctly
* compiled and to ensure that the timers have no effect on program
* execution. Proper use of the macros require that the timer be declared
* before used and that the declaration occur at the same scope as the use
* of timer (or globally as may be necessary when instrumenting functions
* and printing timing results elsewhere). The timer should be stopped
* before being printed (although a running timer will be stopped
* automatically just prior to being printed). The timer need not be
* explicitely started (the implied starting point is the same as the
* declaration if the timer is not explicitely started). All timers
* declared at the same level of scope must have unique names. Previously
* stopped timers must be started in order to accumulate time values across
* multiple stop/run sessions, restarting a timer is performed only to
* re-stablish the starting point.
******************************************************************************/
#if defined(EN_TIME)
/****************************************************************************
* Declare the timer. Initialize the timer (particularly the accumulated
* elapsed time and the timer state).
****************************************************************************/
#define DECLARE_TIMER(A) \
struct { \
/* Start Time - set when the timer is started */ \
clock t Start; \
/* Stop Time - set when the timer is stopped */ \
clock t Stop; \
/* Elapsed Time - Accumulated when the timer is stopped */ \
clock t Elapsed; \
/* Timer State - Set automatically: 0=stopped / 1=running */ \
int State; \
} A = { /* Elapsed Time and State must be initialized to zero */\
/* Start = */ 0, \
/* Stop = */ 0, \
/* Elapsed = */ 0, \
/* State = */ 0, \
}; /* Timer has been declared and defined */
/****************************************************************************
* Start the timer. Print an error if it is already running, set the state
* to running and then start the timer.
****************************************************************************/
#define START_TIMER(A) \
{ \
/* It is an error if the timer is currently running */ \
if (1 == A.State) \
fprintf(stderr, "Error, running timer "#A" started.\n"); \
/* Set the state to running */ \
A.State = 1; \
/* Set the start time, done last to maximize accuracy */ \
A.Start = clock(); \
} /* START TIMER() */
/****************************************************************************
* Reset the timer. Clear the elapsed time.
****************************************************************************/
#define RESET_TIMER(A) \
{ \
/* Reset the elapsed time to zero */ \
A.Elapsed = 0; \
} /* RESET TIMER() */
/****************************************************************************
* Stop the timer. Set the stop time, print an error message if the timer
* is already stopped otherwise accumulate the elapsed time (works for
* both one-time and repeating timing operations), set the state to
* stopped.
****************************************************************************/
#define STOP_TIMER(A) \
{ \
/* Set the stop time, done first to maximize accuracy */ \
A.Stop = clock(); \
/* It is an error if the timer is currently stopped */ \
if (0 == A.State) \
fprintf(stderr, "Error, stopped timer "#A" stopped again.\n"); \
else /* accumulate running total only if previously running */ \
A.Elapsed += A.Stop − A.Start; \
/* Set the state to stopped */ \
A.State = 0; \
} /* STOP TIMER() */
/****************************************************************************
* Print the timer. Check the timer state and stop it if necessary, print
* the elapsed time (in seconds).
****************************************************************************/
#define PRINT TIMER(A) \
{ \
/* Stop the timer (silently) if it is currently running */ \
if (1 == A.State) \
STOP TIMER(A); /* no error possible in this case */ \
fprintf(stderr, "Elapsed CPU Time ("#A") = %g sec.\n", \
(double)A.Elapsed / (double)CLOCKS PER SEC); \
} /*PRINT TIMER() */
#else /* not defined(EN TIME) */
/* Declare null macros for error-free compilation */
#define DECLARE TIMER(A) /* Null Macro */
#define START TIMER(A) /* Null Macro */
#define RESET TIMER(A) /* Null Macro */
#define STOP TIMER(A) /* Null Macro */
#define PRINT TIMER(A) /* Null Macro */
#endif /* defined(EN TIME) */
#endif /* TIMERS H */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment