xref: /phasta/phastaIO/phiotmrc.cc (revision 37dc80d09b1d5d8efb3082d1e16f69bce1775355)
159599516SKenneth E. Jansen #include <stdio.h>
259599516SKenneth E. Jansen #include <sys/types.h>
359599516SKenneth E. Jansen #include <time.h>
459599516SKenneth E. Jansen 
559599516SKenneth E. Jansen #include <sys/time.h>
659599516SKenneth E. Jansen #include <sys/resource.h>
759599516SKenneth E. Jansen #include <unistd.h>
8*37dc80d0SCameron Smith #define __STDC_FORMAT_MACROS /* c++ requires this for the print macros */
9*37dc80d0SCameron Smith #include <inttypes.h> /* PRIu64 */
1059599516SKenneth E. Jansen 
1159599516SKenneth E. Jansen #ifdef __bgq__
1259599516SKenneth E. Jansen #include "hwi/include/bqc/A2_inlines.h"
1359599516SKenneth E. Jansen #endif
1459599516SKenneth E. Jansen 
1559599516SKenneth E. Jansen #include "phiotmrc.h"
16*37dc80d0SCameron Smith #include "phiompi.h"
17*37dc80d0SCameron Smith 
18*37dc80d0SCameron Smith #define BILLION 1000L*1000L*1000L
19*37dc80d0SCameron Smith #define MILLION 1000L*1000L
20*37dc80d0SCameron Smith 
21*37dc80d0SCameron Smith #ifdef __INTEL_COMPILER
22*37dc80d0SCameron Smith typedef size_t phioTime;
23*37dc80d0SCameron Smith size_t phastaio_global_cpus;
24*37dc80d0SCameron Smith size_t phastaio_time_diff(phioTime* start, phioTime* end);
25*37dc80d0SCameron Smith /* return the cycle count */
26*37dc80d0SCameron Smith void phastaio_time(phioTime* t) {
27*37dc80d0SCameron Smith   *t = _rdtsc(); //intel intrinsic
28*37dc80d0SCameron Smith }
29*37dc80d0SCameron Smith /* determine the reference clock frequency */
30*37dc80d0SCameron Smith void phastaio_setCyclesPerMicroSec() {
31*37dc80d0SCameron Smith   const size_t usec = 5*MILLION;
32*37dc80d0SCameron Smith   size_t cpus, cycles;
33*37dc80d0SCameron Smith   phioTime t0, t1;
34*37dc80d0SCameron Smith   phastaio_time(&t0);
35*37dc80d0SCameron Smith   /* Testing on Theta indicates that 5s is long enough
36*37dc80d0SCameron Smith    * to get a stable value for the reference frequency.
37*37dc80d0SCameron Smith    */
38*37dc80d0SCameron Smith   usleep(usec);
39*37dc80d0SCameron Smith   phastaio_time(&t1);
40*37dc80d0SCameron Smith   cycles = t1 - t0;
41*37dc80d0SCameron Smith   cpus = ((double)cycles)/(usec);
42*37dc80d0SCameron Smith   if(!phio_self())
43*37dc80d0SCameron Smith     fprintf(stderr, "cycles %" PRIu64 " us %" PRIu64 " cycles per micro second %" PRIu64"\n", cycles, usec, cpus);
44*37dc80d0SCameron Smith   phastaio_global_cpus = cpus;
45*37dc80d0SCameron Smith }
46*37dc80d0SCameron Smith /*return elapsed time in micro seconds*/
47*37dc80d0SCameron Smith size_t phastaio_time_diff(phioTime* start, phioTime* end) {
48*37dc80d0SCameron Smith   size_t cycles = *end - *start;
49*37dc80d0SCameron Smith   size_t us = ((double)cycles)/phastaio_global_cpus;
50*37dc80d0SCameron Smith   return us;
51*37dc80d0SCameron Smith }
52*37dc80d0SCameron Smith #else
53*37dc80d0SCameron Smith typedef struct timespec phioTime;
54*37dc80d0SCameron Smith void phastaio_time(phioTime* t) {
55*37dc80d0SCameron Smith   int err;
56*37dc80d0SCameron Smith   err = clock_gettime(CLOCK_MONOTONIC,t);
57*37dc80d0SCameron Smith   assert(!err);
58*37dc80d0SCameron Smith }
59*37dc80d0SCameron Smith /*return elapsed time in micro seconds*/
60*37dc80d0SCameron Smith size_t phastaio_time_diff(phioTime* start, phioTime* end) {
61*37dc80d0SCameron Smith   assert(sizeof(size_t)==8);
62*37dc80d0SCameron Smith   size_t elapsed = 0;
63*37dc80d0SCameron Smith   phioTime diff;
64*37dc80d0SCameron Smith   if ((end->tv_nsec-start->tv_nsec)<0) {
65*37dc80d0SCameron Smith     diff.tv_sec = end->tv_sec-start->tv_sec-1;
66*37dc80d0SCameron Smith     diff.tv_nsec = BILLION+end->tv_nsec-start->tv_nsec;
67*37dc80d0SCameron Smith   } else {
68*37dc80d0SCameron Smith     diff.tv_sec = end->tv_sec-start->tv_sec;
69*37dc80d0SCameron Smith     diff.tv_nsec = end->tv_nsec-start->tv_nsec;
70*37dc80d0SCameron Smith   }
71*37dc80d0SCameron Smith   elapsed = (diff.tv_sec)*MILLION + (diff.tv_nsec)/1000L;
72*37dc80d0SCameron Smith   return elapsed;
73*37dc80d0SCameron Smith }
74*37dc80d0SCameron Smith #endif
7559599516SKenneth E. Jansen 
7659599516SKenneth E. Jansen double phiotmrc (void)
7759599516SKenneth E. Jansen {
7859599516SKenneth E. Jansen 
7959599516SKenneth E. Jansen #ifdef __bgq__
8059599516SKenneth E. Jansen 
8159599516SKenneth E. Jansen    // use the GetTimeBase function available on BGQ
8259599516SKenneth E. Jansen    uint64_t TB  = GetTimeBase();
8359599516SKenneth E. Jansen    double t1 = 6.25e-10*TB; // = 1/1.6e9
8459599516SKenneth E. Jansen 
8559599516SKenneth E. Jansen #else
8659599516SKenneth E. Jansen 
8759599516SKenneth E. Jansen   // use the gettimeofday function available on any Linux plateform
8859599516SKenneth E. Jansen 
8959599516SKenneth E. Jansen   int rc;
9059599516SKenneth E. Jansen   struct timeval tv;
9159599516SKenneth E. Jansen 
9259599516SKenneth E. Jansen   rc = gettimeofday (&tv, NULL);
9359599516SKenneth E. Jansen   if (rc == -1) {
9459599516SKenneth E. Jansen     fprintf(stderr,"tmrc: gettimeofday\n");
9559599516SKenneth E. Jansen     return 0.;
9659599516SKenneth E. Jansen   }
9759599516SKenneth E. Jansen   double t1 =  ((double) tv.tv_sec) + 1.e-6 * ((double) tv.tv_usec);
9859599516SKenneth E. Jansen 
9959599516SKenneth E. Jansen #endif
10059599516SKenneth E. Jansen 
10159599516SKenneth E. Jansen   return t1;
10259599516SKenneth E. Jansen 
10359599516SKenneth E. Jansen }
10459599516SKenneth E. Jansen 
105