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