ITAStopWatch.cpp 3.63 KB
Newer Older
Jonas Stienen's avatar
Jonas Stienen committed
1 2 3 4
#include <ITAStopWatch.h>

#include <ITAException.h>

js908001's avatar
js908001 committed
5
#include <string>
Jonas Stienen's avatar
Jonas Stienen committed
6 7 8 9 10 11 12
#include <cmath>
#include <float.h>
#include <sstream>

bool ITAStopWatch::m_bInstanceCreated = false;
double ITAStopWatch::m_dStartStopLatency = 0;

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
13 14
ITAStopWatch::ITAStopWatch()
	: m_pClock( ITAClock::getDefaultClock() )
Jonas Stienen's avatar
Jonas Stienen committed
15 16
{
	// Falls dies die erste Stopwatch ist die erzeugt wird: Latenz messen
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
17
	if( !m_bInstanceCreated ) {
Jonas Stienen's avatar
Jonas Stienen committed
18 19 20 21 22
		ITACriticalSection cs;
		cs.enter();
		start();
		stop();
		reset();
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
23
		for( unsigned int i = 0; i < 100; i++ ) {
Jonas Stienen's avatar
Jonas Stienen committed
24 25 26 27 28 29 30 31
			start();
			stop();
		}
		cs.leave();
		m_dStartStopLatency = minimum();

		/* DEBUG:
		printf("%s: Measured start/stop latency: %0.3f ns\n",
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
32
		__FUNCTION__, _dStartStopLatency * 1000000000);
Jonas Stienen's avatar
Jonas Stienen committed
33 34 35 36 37 38 39 40
		*/

		m_bInstanceCreated = true;
	}

	reset();
}

41 42 43
ITAStopWatch::ITAStopWatch( ITAClock* pClock )
	: m_pClock( pClock )
{
Jonas Stienen's avatar
Jonas Stienen committed
44

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
45 46
	if( !pClock )
		ITA_EXCEPT1( INVALID_PARAMETER, "Clock must not be NULL" );
Jonas Stienen's avatar
Jonas Stienen committed
47 48

	// Falls dies die erste Stopwatch ist die erzeugt wird: Latenz messen
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
49
	if( !m_bInstanceCreated )
50
	{
Jonas Stienen's avatar
Jonas Stienen committed
51 52 53 54 55
		ITACriticalSection cs;
		cs.enter();
		start();
		stop();
		reset();
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
56
		for( unsigned int i = 0; i < 100; i++ )
57
		{
Jonas Stienen's avatar
Jonas Stienen committed
58 59 60 61 62
			start();
			stop();
		}
		cs.leave();
		m_dStartStopLatency = minimum();
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
63

Jonas Stienen's avatar
Jonas Stienen committed
64 65 66 67 68 69
		m_bInstanceCreated = true;
	}

	reset();
}

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
70
void ITAStopWatch::reset()
Jonas Stienen's avatar
Jonas Stienen committed
71 72 73 74 75 76 77 78 79 80 81 82
{
	m_csReadWrite.enter();
	m_uiCycles = 0;
	m_dSum = m_dSquareSum = 0;

	m_dMin = DBL_MAX;
	m_dMax = 0;

	m_bStarted = false;
	m_csReadWrite.leave();
}

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
void ITAStopWatch::start()
{
	m_dStart = m_pClock->getTime();
	m_bStarted = true;
}

bool ITAStopWatch::started() const
{
	return m_bStarted;
}

double ITAStopWatch::stop()
{
	m_dStop = m_pClock->getTime();

	double t = m_dStop - m_dStart - m_dStartStopLatency;

	m_csReadWrite.enter();

	m_dMin = ( std::min )( m_dMin, t );
	m_dMax = ( std::max )( m_dMax, t );
	m_dSum += t;
	m_dSquareSum += ( t*t );
	m_uiCycles++;
	m_bStarted = false;

	m_csReadWrite.leave();
	return t;
}
Jonas Stienen's avatar
Jonas Stienen committed
112 113

unsigned int ITAStopWatch::cycles() const
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
114
{
Jonas Stienen's avatar
Jonas Stienen committed
115 116 117 118 119 120 121
	m_csReadWrite.enter();
	unsigned int uiResult = m_uiCycles;
	m_csReadWrite.leave();
	return uiResult;
}

double ITAStopWatch::minimum() const
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
122 123
{
	return ( m_uiCycles == 0 ? 0 : m_dMin );
Jonas Stienen's avatar
Jonas Stienen committed
124 125
}

126 127
double ITAStopWatch::maximum() const
{
Jonas Stienen's avatar
Jonas Stienen committed
128 129 130 131 132
	return m_dMax;
}

double ITAStopWatch::mean() const
{
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
133
	if( m_csReadWrite.tryenter() == true )
134
	{
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
135
		if( m_uiCycles == 0 )
136
		{
Jonas Stienen's avatar
Jonas Stienen committed
137
			m_csReadWrite.leave();
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
138
			return 0;
Jonas Stienen's avatar
Jonas Stienen committed
139 140 141 142 143 144
		}
		double dResult = m_dSum / m_uiCycles;
		m_csReadWrite.leave();
		return dResult;
	}

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
145
	return 0;
Jonas Stienen's avatar
Jonas Stienen committed
146 147 148 149
}

double ITAStopWatch::variance() const
{
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
150
	if( m_csReadWrite.tryenter() == true )
151
	{
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
152
		if( m_uiCycles == 0 ) {
Jonas Stienen's avatar
Jonas Stienen committed
153
			m_csReadWrite.leave();
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
154
			return 0;
Jonas Stienen's avatar
Jonas Stienen committed
155 156 157
		}

		// Formel: sigma = E(X^2) - E(X)^2
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
158 159
		double x = ( m_dSum / m_uiCycles );
		double dResult = ( m_dSquareSum / m_uiCycles ) - ( x*x );
Jonas Stienen's avatar
Jonas Stienen committed
160 161 162 163
		m_csReadWrite.leave();
		return dResult;
	}

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
164
	return 0;
Jonas Stienen's avatar
Jonas Stienen committed
165 166
}

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
167 168 169
double ITAStopWatch::std_deviation() const
{
	return sqrt( variance() );
Jonas Stienen's avatar
Jonas Stienen committed
170 171
}

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
172
double ITAStopWatch::selftest()
Jonas Stienen's avatar
Jonas Stienen committed
173 174 175 176 177
{
	ITAStopWatch sw;
	sw.start();
	sw.stop();
	sw.reset();
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
178
	for( int i = 0; i < 1000; i++ )
179
	{
Jonas Stienen's avatar
Jonas Stienen committed
180 181 182 183 184 185
		sw.start();
		sw.stop();
	}
	return sw.mean();
}

Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
186
std::string TimeToString( double dTimeSeconds )
Jonas Stienen's avatar
Jonas Stienen committed
187
{
188 189 190
	std::stringstream ss;
	if( dTimeSeconds < 1e-6 )
		ss << dTimeSeconds / 1e-9 << "us";
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
191
	else if( dTimeSeconds < 1e-3 )
192
		ss << dTimeSeconds / 1e-6 << "ns";
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
193
	else if( dTimeSeconds < 1e-0 )
194
		ss << dTimeSeconds / 1e-3 << "ms";
Jonas Stienen's avatar
Jonas Stienen committed
195
	else
196 197 198
		ss << dTimeSeconds << "s";

	return ss.str();
Jonas Stienen's avatar
Jonas Stienen committed
199 200 201 202 203
};

std::string ITAStopWatch::ToString() const
{
	std::ostringstream ss;
Dipl.-Ing. Jonas Stienen's avatar
Style  
Dipl.-Ing. Jonas Stienen committed
204 205 206 207
	ss << "avg=" << TimeToString( mean() ) << ", ";
	ss << "stddev=" << TimeToString( std_deviation() ) << ", ";
	ss << "min=" << TimeToString( minimum() ) << ", ";
	ss << "max=" << TimeToString( maximum() ) << ", ";
Jonas Stienen's avatar
Jonas Stienen committed
208 209 210 211
	ss << "cycles=" << cycles();

	return ss.str();
}