159599516SKenneth E. Jansen #include <stdio.h> 259599516SKenneth E. Jansen #include <sys/types.h> 359599516SKenneth E. Jansen #include <time.h> 459599516SKenneth E. Jansen 559599516SKenneth E. Jansen #include <sys/time.h> 659599516SKenneth E. Jansen #include <sys/resource.h> 759599516SKenneth E. Jansen #include <unistd.h> 8*37dc80d0SCameron Smith #define __STDC_FORMAT_MACROS /* c++ requires this for the print macros */ 9*37dc80d0SCameron Smith #include <inttypes.h> /* PRIu64 */ 1059599516SKenneth E. Jansen 1159599516SKenneth E. Jansen #ifdef __bgq__ 1259599516SKenneth E. Jansen #include "hwi/include/bqc/A2_inlines.h" 1359599516SKenneth E. Jansen #endif 1459599516SKenneth E. Jansen 1559599516SKenneth E. Jansen #include "phiotmrc.h" 16*37dc80d0SCameron Smith #include "phiompi.h" 17*37dc80d0SCameron Smith 18*37dc80d0SCameron Smith #define BILLION 1000L*1000L*1000L 19*37dc80d0SCameron Smith #define MILLION 1000L*1000L 20*37dc80d0SCameron Smith 21*37dc80d0SCameron Smith #ifdef __INTEL_COMPILER 22*37dc80d0SCameron Smith typedef size_t phioTime; 23*37dc80d0SCameron Smith size_t phastaio_global_cpus; 24*37dc80d0SCameron Smith size_t phastaio_time_diff(phioTime* start, phioTime* end); 25*37dc80d0SCameron Smith /* return the cycle count */ 26*37dc80d0SCameron Smith void phastaio_time(phioTime* t) { 27*37dc80d0SCameron Smith *t = _rdtsc(); //intel intrinsic 28*37dc80d0SCameron Smith } 29*37dc80d0SCameron Smith /* determine the reference clock frequency */ 30*37dc80d0SCameron Smith void phastaio_setCyclesPerMicroSec() { 31*37dc80d0SCameron Smith const size_t usec = 5*MILLION; 32*37dc80d0SCameron Smith size_t cpus, cycles; 33*37dc80d0SCameron Smith phioTime t0, t1; 34*37dc80d0SCameron Smith phastaio_time(&t0); 35*37dc80d0SCameron Smith /* Testing on Theta indicates that 5s is long enough 36*37dc80d0SCameron Smith * to get a stable value for the reference frequency. 37*37dc80d0SCameron Smith */ 38*37dc80d0SCameron Smith usleep(usec); 39*37dc80d0SCameron Smith phastaio_time(&t1); 40*37dc80d0SCameron Smith cycles = t1 - t0; 41*37dc80d0SCameron Smith cpus = ((double)cycles)/(usec); 42*37dc80d0SCameron Smith if(!phio_self()) 43*37dc80d0SCameron Smith fprintf(stderr, "cycles %" PRIu64 " us %" PRIu64 " cycles per micro second %" PRIu64"\n", cycles, usec, cpus); 44*37dc80d0SCameron Smith phastaio_global_cpus = cpus; 45*37dc80d0SCameron Smith } 46*37dc80d0SCameron Smith /*return elapsed time in micro seconds*/ 47*37dc80d0SCameron Smith size_t phastaio_time_diff(phioTime* start, phioTime* end) { 48*37dc80d0SCameron Smith size_t cycles = *end - *start; 49*37dc80d0SCameron Smith size_t us = ((double)cycles)/phastaio_global_cpus; 50*37dc80d0SCameron Smith return us; 51*37dc80d0SCameron Smith } 52*37dc80d0SCameron Smith #else 53*37dc80d0SCameron Smith typedef struct timespec phioTime; 54*37dc80d0SCameron Smith void phastaio_time(phioTime* t) { 55*37dc80d0SCameron Smith int err; 56*37dc80d0SCameron Smith err = clock_gettime(CLOCK_MONOTONIC,t); 57*37dc80d0SCameron Smith assert(!err); 58*37dc80d0SCameron Smith } 59*37dc80d0SCameron Smith /*return elapsed time in micro seconds*/ 60*37dc80d0SCameron Smith size_t phastaio_time_diff(phioTime* start, phioTime* end) { 61*37dc80d0SCameron Smith assert(sizeof(size_t)==8); 62*37dc80d0SCameron Smith size_t elapsed = 0; 63*37dc80d0SCameron Smith phioTime diff; 64*37dc80d0SCameron Smith if ((end->tv_nsec-start->tv_nsec)<0) { 65*37dc80d0SCameron Smith diff.tv_sec = end->tv_sec-start->tv_sec-1; 66*37dc80d0SCameron Smith diff.tv_nsec = BILLION+end->tv_nsec-start->tv_nsec; 67*37dc80d0SCameron Smith } else { 68*37dc80d0SCameron Smith diff.tv_sec = end->tv_sec-start->tv_sec; 69*37dc80d0SCameron Smith diff.tv_nsec = end->tv_nsec-start->tv_nsec; 70*37dc80d0SCameron Smith } 71*37dc80d0SCameron Smith elapsed = (diff.tv_sec)*MILLION + (diff.tv_nsec)/1000L; 72*37dc80d0SCameron Smith return elapsed; 73*37dc80d0SCameron Smith } 74*37dc80d0SCameron Smith #endif 7559599516SKenneth E. Jansen 7659599516SKenneth E. Jansen double phiotmrc (void) 7759599516SKenneth E. Jansen { 7859599516SKenneth E. Jansen 7959599516SKenneth E. Jansen #ifdef __bgq__ 8059599516SKenneth E. Jansen 8159599516SKenneth E. Jansen // use the GetTimeBase function available on BGQ 8259599516SKenneth E. Jansen uint64_t TB = GetTimeBase(); 8359599516SKenneth E. Jansen double t1 = 6.25e-10*TB; // = 1/1.6e9 8459599516SKenneth E. Jansen 8559599516SKenneth E. Jansen #else 8659599516SKenneth E. Jansen 8759599516SKenneth E. Jansen // use the gettimeofday function available on any Linux plateform 8859599516SKenneth E. Jansen 8959599516SKenneth E. Jansen int rc; 9059599516SKenneth E. Jansen struct timeval tv; 9159599516SKenneth E. Jansen 9259599516SKenneth E. Jansen rc = gettimeofday (&tv, NULL); 9359599516SKenneth E. Jansen if (rc == -1) { 9459599516SKenneth E. Jansen fprintf(stderr,"tmrc: gettimeofday\n"); 9559599516SKenneth E. Jansen return 0.; 9659599516SKenneth E. Jansen } 9759599516SKenneth E. Jansen double t1 = ((double) tv.tv_sec) + 1.e-6 * ((double) tv.tv_usec); 9859599516SKenneth E. Jansen 9959599516SKenneth E. Jansen #endif 10059599516SKenneth E. Jansen 10159599516SKenneth E. Jansen return t1; 10259599516SKenneth E. Jansen 10359599516SKenneth E. Jansen } 10459599516SKenneth E. Jansen 105