xref: /phasta/phastaIO/phiotmrc.cc (revision e5b451c7cedb3219127f3dfd8ec0556bbfd97a33)
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <time.h>
4 #include <cassert>
5 
6 #include <sys/time.h>
7 #include <sys/resource.h>
8 #include <unistd.h>
9 #define __STDC_FORMAT_MACROS /* c++ requires this for the print macros */
10 #include <inttypes.h> /* PRIu64 */
11 
12 #ifdef __bgq__
13 #include "hwi/include/bqc/A2_inlines.h"
14 #endif
15 
16 #include "phiotmrc.h"
17 #include "phiompi.h"
18 
19 #define BILLION 1000L*1000L*1000L
20 #define MILLION 1000L*1000L
21 
22 #ifdef __INTEL_COMPILER
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 void phastaio_time(phioTime* t) {
54   int err;
55   err = clock_gettime(CLOCK_MONOTONIC,t);
56   assert(!err);
57 }
58 /*return elapsed time in micro seconds*/
59 size_t phastaio_time_diff(phioTime* start, phioTime* end) {
60   assert(sizeof(size_t)==8);
61   size_t elapsed = 0;
62   phioTime diff;
63   if ((end->tv_nsec-start->tv_nsec)<0) {
64     diff.tv_sec = end->tv_sec-start->tv_sec-1;
65     diff.tv_nsec = BILLION+end->tv_nsec-start->tv_nsec;
66   } else {
67     diff.tv_sec = end->tv_sec-start->tv_sec;
68     diff.tv_nsec = end->tv_nsec-start->tv_nsec;
69   }
70   elapsed = (diff.tv_sec)*MILLION + (diff.tv_nsec)/1000L;
71   return elapsed;
72 }
73 #endif
74 
75 double phiotmrc (void)
76 {
77 
78 #ifdef __bgq__
79 
80    // use the GetTimeBase function available on BGQ
81    uint64_t TB  = GetTimeBase();
82    double t1 = 6.25e-10*TB; // = 1/1.6e9
83 
84 #else
85 
86   // use the gettimeofday function available on any Linux plateform
87 
88   int rc;
89   struct timeval tv;
90 
91   rc = gettimeofday (&tv, NULL);
92   if (rc == -1) {
93     fprintf(stderr,"tmrc: gettimeofday\n");
94     return 0.;
95   }
96   double t1 =  ((double) tv.tv_sec) + 1.e-6 * ((double) tv.tv_usec);
97 
98 #endif
99 
100   return t1;
101 
102 }
103 
104