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