C-Breeze
C Compiler Infrastructure

[ Project home page]

cbztimer.h

Go to the documentation of this file.
00001 // $Id: cbztimer.h,v 1.4 2003/08/07 23:14:01 pnav Exp $
00002   /*
00003     High-resolution timer code for Linux.
00004 
00005     Copyright (C) 2002 by Emery Berger.
00006     Copyright (C) 2002 by The University of Massachusetts.
00007     All rights reserved.
00008   */
00009 
00010 #ifndef CBZ_TIMER_H
00011 #define CBZ_TIMER_H
00012 
00013 #include <stdio.h>
00014 #include <limits.h>
00015 #include <time.h>
00016 #include <unistd.h>
00017 #include <fcntl.h>
00018 #include <string.h>
00019 
00020 class cbzTimer
00021 {
00022  public:
00023 
00024   static void getTime (unsigned long& tlo, unsigned long& thi) {
00025 #ifdef __linux__
00026     asm volatile ("rdtsc"
00027                   : "=a"(tlo),
00028                   "=d" (thi));
00029 #endif
00030   }
00031 
00032   
00033   static double getFrequency (void) {
00034     static double freq = 0.0;
00035 #ifdef __linux__
00036     unsigned long LTime0, LTime1, HTime0, HTime1;
00037     if (freq == 0.0) {
00038 
00039       // Parse out the CPU frequency from the /proc/cpuinfo file.
00040 
00041       enum { MAX_PROCFILE_SIZE = 32768 };
00042       const char searchStr[] = "cpu MHz         : ";
00043       static char line[MAX_PROCFILE_SIZE];
00044       int fd = open ("/proc/cpuinfo", O_RDONLY);
00045       read (fd, line, MAX_PROCFILE_SIZE);
00046       char * pos = strstr (line, searchStr);
00047       if (pos == NULL) {
00048 
00049         // Compute MHz directly.
00050         // Wait for approximately one second.
00051 
00052         getTime (LTime0, HTime0);
00053         sleep (1);
00054         getTime (LTime1, HTime1);
00055 
00056         freq = (double)(LTime1 - LTime0) +
00057           (double)(UINT_MAX)*(double)(HTime1 - HTime0);
00058         if(LTime1 < LTime0) { freq -= (double)UINT_MAX; }
00059 
00060         cout << "THIS IS BAD" << endl;
00061 
00062       } else {
00063         // Move the pointer over to the MHz number itself.
00064         pos += strlen(searchStr);
00065         float f;
00066         sscanf (pos, "%f", &f);
00067         freq = ((double) f) * 1000000.0;
00068       }
00069     }
00070 #endif
00071     return freq;
00072   }
00073 
00074 
00075   cbzTimer (void)
00076     : timeElapsed (0.0),
00077       currentLo(0),
00078       currentHi(0)
00079   {}
00080 
00081   void start (void) {
00082     getTime (currentLo, currentHi);
00083   }
00084 
00085   void stop (void) {
00086     unsigned long lo, hi;
00087     getTime (lo, hi);
00088     double d = (double) (lo - currentLo) + (double) (UINT_MAX)*(double)(hi - currentHi);
00089     if (lo < currentLo) {
00090       d -= (double) UINT_MAX;
00091     }
00092     timeElapsed += d;
00093   }
00094 
00095   operator double (void) {
00096     static double freq = getFrequency ();
00097     return timeElapsed / freq;
00098   }
00099 
00100   double time() {
00101     static double freq = getFrequency ();
00102     return timeElapsed / freq;
00103   }
00104   
00105 private:
00106   double timeElapsed;
00107   unsigned long currentLo, currentHi;
00108 };
00109 
00110 #endif

Generated on February 1, 2006
Back to the C-Breeze home page