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