% -*- latex -*-

\chapter{Timers}
\label{chap:Timers}
\label{chap:Timer}

\index{timer|(}

It is often the case that you need to measure the time it takes for an
operation to happen. This could be for performing measurements for
algorithm study or it could be to dynamically adjust scheduling.

Performing timing in a multi-threaded environment can be tricky because operations happen asynchronously.
To ensure that accurate timings can be made, \VTKm provides a \vtkmcont{Timer} class to provide an accurate measurement of operations that happen on devices that \VTKm can use.
By default, \textidentifier{Timer} will time operations on all possible devices.

The timer is started by calling the \classmember{Timer}{Start} method.
The timer can subsequently be stopped by calling \classmember{Timer}{Stop}.
The time elapsed between calls to \classmember*{Timer}{Start} and \classmember*{Timer}{Stop} (or the current time if \classmember*{Timer}{Stop} was not called) can be retrieved with a call to the \classmember{Timer}{GetElapsedTime} method.
Subsequently calling \classmember*{Timer}{Start} again will restart the timer.

\vtkmlisting{Using \protect\vtkmcont{Timer}.}{Timer.cxx}

\begin{commonerrors}
  Some device require data to be copied between the host CPU and the
  device. In this case you might want to measure the time to copy data back
  to the host. This can be done by ``touching'' the data on the host by
  getting a control portal.
\end{commonerrors}

The \VTKm \textidentifier{Timer} does its best to capture the time it takes for all parallel operations run between calls to \classmember*{Timer}{Start} and \classmember*{Timer}{Stop} to complete.
It does so by synchronizing to concurrent execution on devices that might be in use.

\begin{commonerrors}
  Because \textidentifier{Timer} synchronizes with devices (essentially waiting for the device to finish executing), that can have an effect on how your program runs.
  Be aware that using a \textidentifier{Timer} can itself change the performance of your code.
  In particular, starting and stopping the timer many times to measure the parts of a sequence of operations can potentially make the whole operation run slower.
\end{commonerrors}

By default, \textidentifier{Timer} will synchronize with all active devices.
However, if you want to measure the time for a specific device, then you can pass the device adapter tag or id to \vtkmcont{Timer}'s constructor.
You can also change the device being used by passing a device adapter tag or id to the \classmember{Timer}{Reset} method.
A device can also be specified through an optional argument to the \classmember{Timer}{GetElapsedTime} method.

The following methods are provided by \vtkmcont{Timer}.

\begin{description}
\item[{\classmember*{Timer}{Start}}]
  Causes the \textidentifier{Timer} to begin timing.
  The elapsed time will record an interval beginning when this method is called.
\item[{\classmember*{Timer}{Started}}]
  Returns true if \classmember*{Timer}{Start} has been called.
  It is invalid to try to get the elapsed time if \classmember*{Timer}{Started} is not true.
\item[{\classmember*{Timer}{Stop}}]
  Causes the \textidentifier{Timer} to finish timing.
  The elapsed time will record an interval ending when this method is called.
  It is invalid to stop the timer if \classmember*{Timer}{Started} is not true.
\item[{\classmember*{Timer}{Stopped}}]
  Returns true if \classmember*{Timer}{Stop} has been called.
  If \classmember*{Timer}{Stopped} is true, then the elapsed time will no longer increase.
  If \classmember*{Timer}{Stopped} is false and \classmember*{Timer}{Started} is true, then the timer is still running.
\item[{\classmember*{Timer}{Ready}}]
  Returns true if the timer has finished the synchronization required to get the timing result from the device.
\item[{\classmember*{Timer}{GetElapsedTime}}]
  Returns the amount of time that has elapsed between calling \classmember*{Timer}{Start} and \classmember*{Timer}{Stop}.
  If \classmember*{Timer}{Stop} was not called, then the amount of time between calling \classmember*{Timer}{Start} and \classmember*{Timer}{GetElapsedTime} is returned.
  \classmember*{Timer}{GetElapsedTime} can optionally take a device adapter tag or id to specify for which device to return the elapsed time.
\item[{\classmember*{Timer}{Reset}}]
  Restores the initial state of the \textidentifier{Timer}.
  All previous recorded time is erased.
  \classmember*{Timer}{Reset} optionally takes a device adapter tag or id that specifies on which device to time and synchronize.
\item[{\classmember*{Timer}{GetDevice}}]
  Returns the id of the device adapter for which this timer is synchronized.
  If the device adapter has the same id as \vtkmcont{DeviceAdapterTagAny} (the default), then the timer will synchronize on all devices.
\item[{\classmember*{Timer}{Synchronize}}]
  Synchronizes the device returned by \classmember*{Timer}{GetDevice} without starting or stopping the timer.
  This is useful for ensuring that external events are synchronized to the timer.
  Note that this method will always block until all pending operations on the device finish even if the \classmember*{Timer}{Start} or \classmember*{Timer}{Stop} do not actually block.
\end{description}

\index{timer|)}
