summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkarsh Simha <akarsh@kde.org>2016-09-24 05:22:21 (GMT)
committerAkarsh Simha <akarsh@kde.org>2016-09-28 22:16:20 (GMT)
commit25b07e4593ce0c0a41cdb3b706a16a2418fed826 (patch)
tree3cb5dc7949312827cac8266eadfc4812f6da1d30
parent4549930403dbf94f891accb86139bf779b4ff326 (diff)
Profiling Code: Count trigonometric calls on dms, and profile them.
Profiling code I: fraction of dms objects that have sin/cos called This is profiling code to find out what fraction of dms objects hae sin/cos called on them. This is useful to figure out if it makes sense to cache sin/cos values in the constructor itself. It turns out that this might not be a wise decision since the profiling results in at least some context says that it can be as low as 25%: [24 0:15:36 D] KStars::~KStars (186) - Constructed 68504224 dms objects, of which 17021346 had trigonometric functions called on them = 24.8471 % In a different run, it was a bit higher, but still less than 50%. This suggests that it might not be wise to compute and cache sin / cos values upon construction Profiling code II: determine how many trig calls on dms are redundant The initial results of this profiling seem to be staggering! If the simulation clock is running, so we are actually recomputing coordinates, nearly 50% of trigonometric function calls seem to be redundant! This might justify caching the values of sine and cosine upon first computation within dms() itself. This will add a conditional, which can lead to a potential branch mispredict, and some extra stuff, so I'd guess ~ 20 CPU cycles; however, it would save an expensive (~110 CPU cycles) trigonometric function computation almost 50% of the time. Given that a significant fraction (~27% under some particular conditions) of KStars' time is spent on computing sine and cosine, it might be well worth it to save these calls. CCMAIL: kstars-devel@kde.org
-rw-r--r--kstars/auxiliary/dms.cpp19
-rw-r--r--kstars/auxiliary/dms.h92
-rw-r--r--kstars/kstars.cpp9
3 files changed, 113 insertions, 7 deletions
diff --git a/kstars/auxiliary/dms.cpp b/kstars/auxiliary/dms.cpp
index bf30535..be1de35 100644
--- a/kstars/auxiliary/dms.cpp
+++ b/kstars/auxiliary/dms.cpp
@@ -23,22 +23,41 @@
#include <cstdlib>
+#ifdef COUNT_DMS_SINCOS_CALLS
+long unsigned dms::dms_constructor_calls = 0;
+long unsigned dms::dms_with_sincos_called = 0;
+long unsigned dms::trig_function_calls = 0;
+long unsigned dms::redundant_trig_function_calls = 0;
+#endif
+
void dms::setD(const int &d, const int &m, const int &s, const int &ms) {
D = (double)abs(d) + ((double)m + ((double)s + (double)ms/1000.)/60.)/60.;
if (d<0) {D = -1.0*D;}
+#ifdef COUNT_DMS_SINCOS_CALLS
+ m_cosDirty = m_sinDirty = true;
+#endif
}
void dms::setH( const double &x ) {
setD( x*15.0 );
+#ifdef COUNT_DMS_SINCOS_CALLS
+ m_cosDirty = m_sinDirty = true;
+#endif
}
void dms::setH(const int &h, const int &m, const int &s, const int &ms) {
D = 15.0*((double)abs(h) + ((double)m + ((double)s + (double)ms/1000.)/60.)/60.);
if (h<0) {D = -1.0*D;}
+#ifdef COUNT_DMS_SINCOS_CALLS
+ m_cosDirty = m_sinDirty = true;
+#endif
}
void dms::setRadians( const double &Rad ) {
setD( Rad/DegToRad );
+#ifdef COUNT_DMS_SINCOS_CALLS
+ m_cosDirty = m_sinDirty = true;
+#endif
}
bool dms::setFromString( const QString &str, bool isDeg ) {
diff --git a/kstars/auxiliary/dms.h b/kstars/auxiliary/dms.h
index 8ff8e8c..28ce633 100644
--- a/kstars/auxiliary/dms.h
+++ b/kstars/auxiliary/dms.h
@@ -25,6 +25,7 @@
#include <cmath>
+#define COUNT_DMS_SINCOS_CALLS true
/** @class dms
* @short An angle, stored as degrees, but expressible in many ways.
@@ -43,7 +44,15 @@
class dms {
public:
/** Default constructor. */
- dms() : D( NaN::d ) {}
+ dms() : D( NaN::d )
+#ifdef COUNT_DMS_SINCOS_CALLS
+ , m_sinCosCalled(false), m_sinDirty( true ), m_cosDirty( true )
+#endif
+ {
+#ifdef COUNT_DMS_SINCOS_CALLS
+ ++dms_constructor_calls;
+#endif
+ }
/** @short Set the floating-point value of the angle according to the four integer arguments.
* @param d degree portion of angle (int). Defaults to zero.
@@ -51,14 +60,30 @@ public:
* @param s arcsecond portion of angle (int). Defaults to zero.
* @param ms arcsecond portion of angle (int). Defaults to zero.
*/
- explicit dms( const int &d, const int &m=0, const int &s=0, const int &ms=0 ) { setD( d, m, s, ms ); }
+ explicit dms( const int &d, const int &m=0, const int &s=0, const int &ms=0 )
+#ifdef COUNT_DMS_SINCOS_CALLS
+ : m_sinCosCalled(false), m_sinDirty( true ), m_cosDirty( true )
+#endif
+ { setD( d, m, s, ms );
+#ifdef COUNT_DMS_SINCOS_CALLS
+ ++dms_constructor_calls;
+#endif
+}
/** @short Construct an angle from a double value.
*
* Creates an angle whose value in Degrees is equal to the argument.
* @param x angle expressed as a floating-point number (in degrees)
*/
- explicit dms( const double &x ) : D(x) {}
+ explicit dms( const double &x ) : D(x)
+#ifdef COUNT_DMS_SINCOS_CALLS
+ , m_sinCosCalled(false), m_sinDirty( true ), m_cosDirty( true )
+#endif
+ {
+#ifdef COUNT_DMS_SINCOS_CALLS
+ ++dms_constructor_calls;
+#endif
+ }
/** @short Construct an angle from a string representation.
*
@@ -73,7 +98,15 @@ public:
* @param isDeg if true, value is in degrees; if false, value is in hours.
* @sa setFromString()
*/
- explicit dms( const QString &s, bool isDeg=true ) { setFromString( s, isDeg ); }
+ explicit dms( const QString &s, bool isDeg=true )
+#ifdef COUNT_DMS_SINCOS_CALLS
+ : m_sinCosCalled(false), m_sinDirty( true ), m_cosDirty( true )
+#endif
+ { setFromString( s, isDeg );
+#ifdef COUNT_DMS_SINCOS_CALLS
+ ++dms_constructor_calls;
+#endif
+ }
/** @return integer degrees portion of the angle
*/
@@ -128,7 +161,11 @@ public:
/** Sets floating-point value of angle, in degrees.
* @param x new angle (double)
*/
- void setD( const double &x ) { D = x; }
+ void setD( const double &x ) {
+#ifdef COUNT_DMS_SINCOS_CALLS
+ m_sinDirty = m_cosDirty = true;
+#endif
+ D = x; }
/** @short Sets floating-point value of angle, in degrees.
*
@@ -195,14 +232,32 @@ public:
* @return the Sine of the angle.
* @sa cos()
*/
- double sin() const { return ::sin(D*DegToRad); }
+ double sin() const {
+#ifdef COUNT_DMS_SINCOS_CALLS
+ if( !m_sinCosCalled ) { m_sinCosCalled = true; ++dms_with_sincos_called; }
+ if( m_sinDirty )
+ m_sinDirty = false;
+ else
+ ++redundant_trig_function_calls;
+ ++trig_function_calls;
+#endif
+ return ::sin(D*DegToRad); }
/** @short Compute the Angle's Cosine.
*
* @return the Cosine of the angle.
* @sa sin()
*/
- double cos() const { return ::cos(D*DegToRad); }
+ double cos() const {
+#ifdef COUNT_DMS_SINCOS_CALLS
+ if( !m_sinCosCalled ) { m_sinCosCalled = true; ++dms_with_sincos_called; }
+ if( m_cosDirty )
+ m_cosDirty = false;
+ else
+ ++redundant_trig_function_calls;
+ ++trig_function_calls;
+#endif
+ return ::cos(D*DegToRad); }
/** @short Express the angle in radians.
* @return the angle in radians (double)
@@ -261,8 +316,17 @@ public:
static dms fromString(const QString & s, bool deg);
dms operator - () { return dms(-D); }
+#ifdef COUNT_DMS_SINCOS_CALLS
+ static long unsigned dms_constructor_calls; // counts number of DMS constructor calls
+ static long unsigned dms_with_sincos_called;
+ static long unsigned trig_function_calls; // total number of trig function calls
+ static long unsigned redundant_trig_function_calls; // counts number of redundant trig function calls
+#endif
private:
double D;
+#ifdef COUNT_DMS_SINCOS_CALLS
+ mutable bool m_sinDirty, m_cosDirty, m_sinCosCalled;
+#endif
friend dms operator+(dms, dms);
friend dms operator-(dms, dms);
@@ -294,6 +358,20 @@ inline void dms::SinCos(double& s, double& c) const {
s = ::sin( radians() );
c = ::cos( radians() );
#endif
+#ifdef COUNT_DMS_SINCOS_CALLS
+ if( !m_sinCosCalled ) { m_sinCosCalled = true; ++dms_with_sincos_called; }
+ if( m_sinDirty )
+ m_sinDirty = false;
+ else
+ ++redundant_trig_function_calls;
+
+ if( m_cosDirty )
+ m_cosDirty = false;
+ else
+ ++redundant_trig_function_calls;
+
+ trig_function_calls += 2;
+#endif
}
/** Overloaded equality operator */
diff --git a/kstars/kstars.cpp b/kstars/kstars.cpp
index d8ca2df..f4076f8 100644
--- a/kstars/kstars.cpp
+++ b/kstars/kstars.cpp
@@ -42,6 +42,9 @@
#include "observinglist.h"
//#include "whatsinteresting/wiview.h"
+// For profiling only
+#include "auxiliary/dms.h"
+
#include "kstarsadaptor.h"
#include <config-kstars.h>
@@ -173,6 +176,12 @@ KStars::~KStars()
QSqlDatabase::removeDatabase("userdb");
QSqlDatabase::removeDatabase("skydb");
+
+#ifdef COUNT_DMS_SINCOS_CALLS
+ qDebug() << "Constructed " << dms::dms_constructor_calls << " dms objects, of which " << dms::dms_with_sincos_called << " had trigonometric functions called on them = " << ( float( dms::dms_with_sincos_called ) / float( dms::dms_constructor_calls ) ) * 100. << "%";
+ qDebug() << "Of the " << dms::trig_function_calls << " calls to sin/cos/sincos on dms objects, " << dms::redundant_trig_function_calls << " were redundant = " << ( ( float( dms::redundant_trig_function_calls ) / float( dms::trig_function_calls ) ) * 100. ) << "%";
+#endif
+
}
void KStars::clearCachedFindDialog() {