xref: /phasta/phastaIO/phiotmrc.cc (revision 37dc80d09b1d5d8efb3082d1e16f69bce1775355)
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <time.h>
4 
5 #include <sys/time.h>
6 #include <sys/resource.h>
7 #include <unistd.h>
8 #define __STDC_FORMAT_MACROS /* c++ requires this for the print macros */
9 #include <inttypes.h> /* PRIu64 */
10 
11 #ifdef __bgq__
12 #include "hwi/include/bqc/A2_inlines.h"
13 #endif
14 
15 #include "phiotmrc.h"
16 #include "phiompi.h"
17 
18 #define BILLION 1000L*1000L*1000L
19 #define MILLION 1000L*1000L
20 
21 #ifdef __INTEL_COMPILER
22 typedef size_t phioTime;
23 size_t phastaio_global_cpus;
24 size_t phastaio_time_diff(phioTime* start, phioTime* end);
25 /* return the cycle count */
26 void phastaio_time(phioTime* t) {
27   *t = _rdtsc(); //intel intrinsic
28 }
29 /* determine the reference clock frequency */
30 void phastaio_setCyclesPerMicroSec() {
31   const size_t usec = 5*MILLION;
32   size_t cpus, cycles;
33   phioTime t0, t1;
34   phastaio_time(&t0);
35   /* Testing on Theta indicates that 5s is long enough
36    * to get a stable value for the reference frequency.
37    */
38   usleep(usec);
39   phastaio_time(&t1);
40   cycles = t1 - t0;
41   cpus = ((double)cycles)/(usec);
42   if(!phio_self())
43     fprintf(stderr, "cycles %" PRIu64 " us %" PRIu64 " cycles per micro second %" PRIu64"\n", cycles, usec, cpus);
44   phastaio_global_cpus = cpus;
45 }
46 /*return elapsed time in micro seconds*/
47 size_t phastaio_time_diff(phioTime* start, phioTime* end) {
48   size_t cycles = *end - *start;
49   size_t us = ((double)cycles)/phastaio_global_cpus;
50   return us;
51 }
52 #else
53 typedef struct timespec phioTime;
54 void phastaio_time(phioTime* t) {
55   int err;
56   err = clock_gettime(CLOCK_MONOTONIC,t);
57   assert(!err);
58 }
59 /*return elapsed time in micro seconds*/
60 size_t phastaio_time_diff(phioTime* start, phioTime* end) {
61   assert(sizeof(size_t)==8);
62   size_t elapsed = 0;
63   phioTime diff;
64   if ((end->tv_nsec-start->tv_nsec)<0) {
65     diff.tv_sec = end->tv_sec-start->tv_sec-1;
66     diff.tv_nsec = BILLION+end->tv_nsec-start->tv_nsec;
67   } else {
68     diff.tv_sec = end->tv_sec-start->tv_sec;
69     diff.tv_nsec = end->tv_nsec-start->tv_nsec;
70   }
71   elapsed = (diff.tv_sec)*MILLION + (diff.tv_nsec)/1000L;
72   return elapsed;
73 }
74 #endif
75 
76 double phiotmrc (void)
77 {
78 
79 #ifdef __bgq__
80 
81    // use the GetTimeBase function available on BGQ
82    uint64_t TB  = GetTimeBase();
83    double t1 = 6.25e-10*TB; // = 1/1.6e9
84 
85 #else
86 
87   // use the gettimeofday function available on any Linux plateform
88 
89   int rc;
90   struct timeval tv;
91 
92   rc = gettimeofday (&tv, NULL);
93   if (rc == -1) {
94     fprintf(stderr,"tmrc: gettimeofday\n");
95     return 0.;
96   }
97   double t1 =  ((double) tv.tv_sec) + 1.e-6 * ((double) tv.tv_usec);
98 
99 #endif
100 
101   return t1;
102 
103 }
104 
105