ITAStopWatch.h 5.34 KB
Newer Older
Jonas Stienen's avatar
Jonas Stienen committed
1
/*
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
 * ----------------------------------------------------------------
 *
 *		ITA core libs
 *		(c) Copyright Institute of Technical Acoustics (ITA)
 *		RWTH Aachen University, Germany, 2015-2017
 *
 * ----------------------------------------------------------------
 *				    ____  __________  _______
 *				   //  / //__   ___/ //  _   |
 *				  //  /    //  /    //  /_|  |
 *				 //  /    //  /    //  ___   |
 *				//__/    //__/    //__/   |__|
 *
 * ----------------------------------------------------------------
 *
 */
Jonas Stienen's avatar
Jonas Stienen committed
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68

#ifndef INCLUDE_WATCHER_ITA_STOP_WATCH
#define INCLUDE_WATCHER_ITA_STOP_WATCH

// ITABase
#include <ITABaseDefinitions.h>
#include <ITAClock.h>
#include <ITACriticalSection.h>

#include <algorithm>

//! Eine Klasse zum Messen von Zeitintervallen
/**
 * ISPL::Stopwatch ist eine Klasse, welche die Funktionalität des
 * Zeitmessens wie mit einer Stoppuhr realisiert. Dazu verwendet
 * die Klasse die High Performance Timer (HPT). Ferner bietet sie
 * die Möglichkeit den Durchschnittswert der gemessenen Zeiten zu
 * ermitteln, was bei Benchmarking-Anwendung interessant ist.
 *
 * \important Die Klasse ist nicht (mehr) Thread-Safe! Um eine hohe
 *            Messgenauigkeit zu erreichen, wurde auf
 *            Synchronisationsmechanismen verzichtet. Sie müssen
 *            in ihrem Code selbst dafür Sorgen, das Zugriffe auf die
 *            Methoden von Instanzen der Klasse exklusiv geschehen!
 */

class ITA_BASE_API ITAStopWatch
{
public:
	//! Konstruktor
	ITAStopWatch();

	//! Konstruktor
	ITAStopWatch(ITAClock* pClock);

	//! Zurücksetzen
	/**
	 * Setzt den internen Zähler für die Anzahl der Messzyklen,
	 * sowie den Minimal-, Maximal- und Mittelwert zurück.
	 *
	 * \note Laufende Zeitnahmen werden abgebrochen
	 */
	void reset();

	//! Feststellen ob die Zeitnahme bereits gestartet wurde
	bool started() const;

	//! Zeitnahme beginnen
	/**
	 * \note Wurde bereits die Zeitnahme gestartet, wird eine Ausnahme ausgelöst
	 */
69
	void start();
Jonas Stienen's avatar
Jonas Stienen committed
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173

	//! Zeitnahme stoppen
	/**
	 * Stoppt die aktuelle Zeitnahme und gibt die Dauer des gemessenen
	 * Zeitintervalls in Sekunden zurück.
	 *
	 * \return Gemessenes Zeitinterval [in Sekunden]
	 *
	 * \note Ist keine Zeitnahme gestartet, wird eine Ausnahme ausgelöst
	 */
	double stop();

	//! Anzahl der gemessenen Zeitintervalle (Messzyklen) zurückgeben
	unsigned int cycles() const;

	//! Setzt Anzahl der berücksichtigten Zeitintervalle (Messzyklen)
	// Deprecated: void setMaxCycles(unsigned int uiMaxCycles);

	//! Kürzeste gemessene Zeit zurückgeben
	/**
	 * \return Kürzeste gemessene Zeit [in Sekunden]
	 * \note Wurden noch keine Messungen durchgeführt, ist der Rückgabewert 0
	 */
	double minimum() const;

	//! Längste gemessene Zeit zurückgeben
	/**
	 * \return Längste gemessene Zeit [in Sekunden]
	 * \note Wurden noch keine Messungen durchgeführt, ist der Rückgabewert 0
	 */
	double maximum() const;

	//! Summierte Laufzeiten seit dem letzten Reset aller gemessenen Zeiten zurückgeben
	/**
	 * \return Summe aller gemessenen Zeiten [in Sekunden]
	 * \note Wurden noch keine Messungen durchgeführt, ist der Rückgabewert 0
	 */
	inline double sum()
	{
		return m_dSum;
	}

	//! Arithmetischer Mittelwert (mean) aller gemessenen Zeiten zurückgeben
	/**
	 * \return Arithmetischer Mittelwert (mean) aller gemessenen Zeiten [in Sekunden]
	 * \note Wurden noch keine Messungen durchgeführt, ist der Rückgabewert 0
	 */
	double mean() const;

	//! Varianz (Moment 2. Ordnung) aller gemessenen Zeiten zurückgeben
	/**
	 * Die Varianz (das Moment 2. Ordnung) aller gemessenen Zeiten berechnet
	 * sich zu omega = sqrt( 1/n * sum_over_x[i](mju - x[i]) ), wobei
	 * mju der arithmethische Mittelwert (mean, oder auch Erwartungswert)
	 * und die x[i] die Messwerte sind.

	 * \return Varianz aller gemessenen Zeiten [in Sekunden]
	 * \note Wurden noch keine Messungen durchgeführt, ist der Rückgabewert 0
	 */
	double variance() const;

	//! Standardabweichung aller gemessenen Zeiten zurückgeben
	/**
	 * Die Standardabweichung aller gemessenen Zeiten berechnet
	 * sich als Quadratwurzel der Varianz.
     *
	 * \return Standardabweichung aller gemessenen Zeiten [in Sekunden]
	 * \note Wurden noch keine Messungen durchgeführt, ist der Rückgabewert 0
	 */
	double std_deviation() const;

	//! Selbsttest durchführen
	/**
	 * Diese Methode misst den Durchschnittswert der Dauer zwischen
	 * zwei direkten aufeinanderfolgenden Aufrufen der Methoden
	 * start() und stop(). Idealerweise sollte dieser Wert nahe 0 sein.
	 * (Hinweis: Die Stopwatch berücksichtigt eine Grundlatenz (Verzögerung
	 * zwischen Aufrufen von start() und stop()), welche von allen Messwerten
	 * abgezogen wird die stop() zurückgibt).
     *
	 * In der Praxis ergeben sich größere Werte, falls im Debug-Modus
	 * kompiliert wurde. In allen Fällen sollte der Wert aber <= 1ns sein.
	 * (Testsystem: Pentium M 1.4 GHz)
	 *
	 * \return Durchschnittsdauer in Sekunden
	 */
	 static double selftest();

	//! Einen formattierten String ausgeben, der den status der Stopwatch formuliert
	std::string ToString() const;

private:
	bool m_bStarted;
	double m_dStart, m_dStop;
	double m_dSum, m_dSquareSum, m_dMin, m_dMax;
	unsigned int m_uiCycles;

	ITAClock* m_pClock;
	static bool m_bInstanceCreated;	// Bereits eine Instanz dieser Klasse erzeugt?
	static double m_dStartStopLatency;	// Latenz zwischen Start/Stop (Messfehler)
	ITACriticalSection m_csReadWrite;
};

#endif // INCLUDE_WATCHER_ITA_STOP_WATCH