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