aboutsummaryrefslogtreecommitdiff
path: root/Carpet/CycleClock/src/clock.cc
diff options
context:
space:
mode:
Diffstat (limited to 'Carpet/CycleClock/src/clock.cc')
-rw-r--r--Carpet/CycleClock/src/clock.cc177
1 files changed, 177 insertions, 0 deletions
diff --git a/Carpet/CycleClock/src/clock.cc b/Carpet/CycleClock/src/clock.cc
new file mode 100644
index 000000000..26e251ca1
--- /dev/null
+++ b/Carpet/CycleClock/src/clock.cc
@@ -0,0 +1,177 @@
+#include "cycleclock.h"
+
+#include <cctk.h>
+
+#include <cmath>
+
+
+
+namespace CycleClock {
+
+ using namespace std;
+
+
+
+ class cycleclock_t {
+ double sum;
+ double sum2;
+ double min;
+ double max;
+ double count;
+
+ ticks last;
+
+ public:
+ cycleclock_t()
+ {
+ reset();
+ }
+
+ ~cycleclock_t()
+ {
+ }
+
+ void start()
+ {
+ last = getticks();
+ }
+
+ void stop()
+ {
+ ticks const current = getticks();
+ double const difference = elapsed(current, last);
+ sum += difference;
+ sum2 += pow(difference, 2.0);
+ min = min == 0.0 ? difference : fmin(min, difference);
+ max = fmax(min, difference);
+ count += 1.0;
+ }
+
+ void reset()
+ {
+ sum = 0.0;
+ sum2 = 0.0;
+ min = 0.0; // numeric_limits<double>::max();
+ max = 0.0;
+ count = 0.0;
+ }
+
+ void get(cTimerVal* restrict const vals) const
+ {
+ double const tick = seconds_per_tick();
+
+ // Sum time
+ vals[0].type = val_double;
+ vals[0].heading = "cycle";
+ vals[0].units = "secs";
+ vals[0].val.d = sum;
+ vals[0].seconds = tick * vals[0].val.d;
+ vals[0].resolution = tick;
+
+ // Average
+ vals[1].type = val_double;
+ vals[1].heading = "cycle[avg]";
+ vals[1].units = "secs";
+ vals[1].val.d = count == 0.0 ? 0.0 : sum / count;
+ vals[1].seconds = tick * vals[1].val.d;
+ vals[1].resolution = tick;
+
+ // Standard deviation
+ vals[2].type = val_double;
+ vals[2].heading = "cycle[sdv]";
+ vals[2].units = "secs";
+ vals[2].val.d = (count == 0.0 ?
+ 0.0 :
+ sqrt(fabs(sum2 * count - pow(sum, 2.0)) / count));
+ vals[2].seconds = tick * vals[2].val.d;
+ vals[2].resolution = tick;
+
+ // Minimum
+ vals[3].type = val_double;
+ vals[3].heading = "cycle[min]";
+ vals[3].units = "secs";
+ vals[3].val.d = min;
+ vals[3].seconds = tick * vals[3].val.d;
+ vals[3].resolution = tick;
+
+ // Maximum
+ vals[4].type = val_double;
+ vals[4].heading = "cycle[max]";
+ vals[4].units = "secs";
+ vals[4].val.d = max;
+ vals[4].seconds = tick * vals[4].val.d;
+ vals[4].resolution = tick;
+ }
+
+ void set(cTimerVal const* restrict const vals)
+ {
+ reset(); // punt
+ sum = vals[0].val.d;
+ }
+ };
+
+
+
+ void* cycleclock_create(int const timernum)
+ {
+ return new cycleclock_t;
+ }
+
+ void cycleclock_destroy(int const timernum, void* const data)
+ {
+ if (!data) return;
+ delete static_cast<cycleclock_t*>(data);
+ }
+
+ void cycleclock_start(int const timernum, void* const data)
+ {
+ static_cast<cycleclock_t*>(data)->start();
+ }
+
+ void cycleclock_stop(int const timernum, void* const data)
+ {
+ static_cast<cycleclock_t*>(data)->stop();
+ }
+
+ void cycleclock_reset(int const timernum, void* const data)
+ {
+ static_cast<cycleclock_t*>(data)->reset();
+ }
+
+ void cycleclock_get(int const timernum, void* const data,
+ cTimerVal* const vals)
+ {
+ static_cast<cycleclock_t const*>(data)->get(vals);
+ }
+
+ void cycleclock_set(int const timernum, void* const data,
+ cTimerVal* const vals)
+ {
+ static_cast<cycleclock_t*>(data)->set(vals);
+ }
+
+ void cycleclock_register()
+ {
+ cClockFuncs functions;
+ functions.n_vals = 5;
+ functions.create = cycleclock_create;
+ functions.destroy = cycleclock_destroy;
+ functions.start = cycleclock_start;
+ functions.stop = cycleclock_stop;
+ functions.reset = cycleclock_reset;
+ functions.get = cycleclock_get;
+ functions.set = cycleclock_set;
+ CCTK_ClockRegister("cycle", &functions);
+ }
+
+
+
+ extern "C"
+ int CycleClock_Setup()
+ {
+ measure_tick();
+ cycleclock_register();
+ return 0;
+ }
+
+} // namespace CycleClock