1
2The stopwatch module measures the elapsed (wall clock) time, CPU time,
3and system time consumed by any part of a program.
4
5The simple way to measure the CPU time consumption in an ANSI C
6program is:
7
8\begin{cchunk}
9    clock_t  t0, t1;
10    t0 = clock();
11    /* do_stuff */
12    t1 = clock();
13    printf("cpu time: %.2f\n", (double) (t1-t0)/(double) CLOCKS_PER_SEC);
14\end{cchunk}
15
16The stopwatch module is just an elaboration of this.  It tracks
17elapsed and system time, in addition to cpu time; it hides the details
18of converting a time difference in hardware clock ticks to a
19human-interpretable time in seconds; and it provides a standard output
20function for formatting times, similar to the output of the standard
21UNIX \ccode{time} command line utility for timing processes.
22
23\begin{table}[hb]
24\begin{tabular}{ll}\hline
25\ccode{esl\_stopwatch\_Create()}  & Creates new stopwatch.\\
26\ccode{esl\_stopwatch\_Destroy()} & Frees a stopwatch.\\
27\ccode{esl\_stopwatch\_Start()}   & Starts a stopwatch.\\
28\ccode{esl\_stopwatch\_Stop()}    & Stops a stopwatch.\\
29\ccode{esl\_stopwatch\_Display()} & Displays elapsed, cpu, and system time.\\
30\ccode{esl\_stopwatch\_Include()} & Merges a stopwatch's time into a master.\\
31\hline
32\end{tabular}
33\caption{The \eslmod{stopwatch} API.}
34\label{tbl:stopwatch_api}
35\end{table}
36
37Table~\ref{tbl:stopwatch_api} lists the functions in the API.
38
39Starting a stopwatch with \ccode{esl\_stopwatch\_Start()} initializes
40a base time, t0. Stopping a stopwatch with
41\ccode{esl\_stopwatch\_Stop()} takes the current time t1, and
42internally computes and stores elapsed, cpu, and system time
43differences (t1-t0). These stored times can be displayed at any time
44using \ccode{esl\_stopwatch\_Display()}, until the next time the watch
45is stopped. A stopwatch can be stopped any number of times, measuring
46increasing time from the same base. A stopwatch can also be started
47any number of times, resetting the base each time it is set.
48
49Figure~\ref{fig:stopwatch_example} shows a small example that measures
50a boring \ccode{sleep(5)} call, which will of course show an elapsed
51wall time of 5 seconds.  Change the \ccode{sleep(5)} call to something
52cpu- or system-intensive to see a non-zero measurement of cpu or
53system time.
54
55\begin{figure}
56\input{cexcerpts/stopwatch_example}
57\caption{An example of using the \eslmod{stopwatch} module.}
58\label{fig:stopwatch_example}
59\end{figure}
60
61\subsection{Displaying and retrieving times}
62
63The \ccode{esl\_stopwatch\_Display()} function prints a line
64containing the cpu time, system time, aggregated cpu+system time, and
65the elapsed (wall clock) time. For example:
66
67\begin{cchunk}
68CPU Time: 142.55u 7.17s 00:02:29.72 Elapsed: 00:02:35
69\end{cchunk}
70
71If you want to access the times in seconds for your own purposes, the
72relevant fields in a stopped \ccode{ESL\_STOPWATCH} object are:
73
74\begin{cchunk}
75  double elapsed;               /* elapsed time, seconds */
76  double user;                  /* CPU time, seconds     */
77  double sys;                   /* system time, seconds  */
78\end{cchunk}
79
80
81
82\subsection{Stopwatch precision and system dependency}
83
84Elapsed wall time is typically measured at low resolution, in units of
85seconds (depending on the ANSI C \ccode{time\_t} definition on your
86system). It is displayed with a precision of 1 sec.
87
88CPU time is typically measured in high resolution, in units of
89microseconds (depending on the value of POSIX \ccode{\_SC\_CLK\_TCK} or
90ANSI C \ccode{CLOCKS\_PER\_SEC} on your system). It is displayed with a
91precision of 0.01 sec.
92
93System time is only determined on systems that provide a POSIX
94\ccode{times()} function. Like CPU time, it is typically measured at
95high resolution, in units of microseconds (depending on the POSIX
96\ccode{\_SC\_CLK\_TCK} value on your system). It is displayed with a
97precision of 0.01 sec.  On systems that do not provide a
98POSIX-compliant \ccode{times()} function, system time is always
99reported as 0.
100
101\subsection{Aggregate times in parallelized code}
102
103In parallelized code, you may want to aggregate results from multiple
104stopwatches into a single overall time measurement. Examples include
105aggregating times from worker processes in PVM or MPI applications, or
106aggregating times from multiple execution threads on systems where the
107\ccode{times()} function does not correctly aggregate threads for you.
108
109The \ccode{esl\_stopwatch\_Include()} function adds the cpu and system
110times in a ``client'' stopwatch to a ``master'' stopwatch. Both the
111client and the master stopwatch must be stopped. The elapsed time in
112the master stopwatch is not affected; it is assumed to be keeping
113track of the real (wall clock) time.
114
115
116
117
118